Migrating from CrinGraph
This page is for operators moving an existing CrinGraph database — or any of its popular derivatives — to modernGraphTool v2.
The good news: the core data (FR .txt files, phone_book.json, target files) is format-compatible and carries over without modification. The work is mostly in restructuring the data/ folder, regenerating the config in v2’s format, and re-applying page metadata.
Which fork are you coming from?
Section titled “Which fork are you coming from?”CrinGraph has a long history and several actively maintained forks. The migration steps are largely the same, but each fork has structural quirks worth naming up front.
| Vanilla CrinGraph | squiglink lab | PublicGraphTool | |
|---|---|---|---|
| Config file | config.js (root) | config.js (root), config_hp.js for HP variant | assets/js/config.js |
| Phone FR files | data/*.txt (flat) | data/*.txt (flat) | data/*.txt (flat) |
| Target files | data/*.txt (mixed with phones) | data/*.txt (mixed with phones) | Split: some in data/*Target.txt, more in data/targets/ |
phone_book.json | Optional (often absent) | data/phone_book.json | data/phone_book.json |
| Preference bounds | None | None | assets/pref_bounds/Bounds L.txt + Bounds R.txt |
| Theme CSS | style*.css at root | style*.css + styles/dark.css + styles/white.css | assets/css/extra.css + style*.css |
| Headphones variant | Usually a separate install | data_hp/ folder + config_hp.js | data_hp/ folder + headphones.html + config_hp.js |
| External scripts | None | None | squigsites.js, reinvented-color-wheel.min.js, 90inclusion.js, audio tags |
If your fork isn’t listed here, it almost certainly behaves like one of these three. The steps below call out fork-specific differences inline as Lab, PublicGraphTool, and Vanilla notes.
Compatibility
Section titled “Compatibility”Format-compatible, carries over unchanged:
- FR measurement
.txtfiles (tab/space-separatedfreq dBcolumns) - Target
.txtfiles (same format) phone_book.jsonschema (see Managing Data if you need to create one)- Watermark images, logos, favicon images
Not compatible, needs regeneration:
config.js— CrinGraph uses top-levelconstbindings (const init_phones = [...], DIR = "data/"); v2 uses a single structuredCONFIG = { ... }object. The fields are mostly equivalent but the format is entirely different.- Theme/stylesheet CSS — CrinGraph’s styles are scattered across multiple files with hard-coded hex values; v2 uses a single
theme.csswith CSS custom properties (OKLCH-based). - Folder layout — CrinGraph keeps phones and targets mixed in a single
data/folder; v2 expects them split intodata/phones/anddata/target/.
Does not carry over at all:
- CrinGraph’s JS files (
graphtool.js,equalizer.js,listAugment.js,saveSvgAsPng.js,graphAnalytics.js) - Bundled libraries (
d3.v5.min.js,fuse.min.js,reinvented-color-wheel.min.js) - External scripts pulled from
squig.link/squigsites.js— v2 has native squig.link integration via theSQUIGLINKconfig section. Remove the script tag.
Migration Steps
Section titled “Migration Steps”-
Download the latest modernGraphTool v2 release and extract it.
-
Restructure your
data/folder. v2 expects phones and targets in separate subfolders:data/├── phones/ # all your phone FR .txt files│ ├── IEM A L.txt│ ├── IEM A R.txt│ └── ...├── target/ # all your target curve .txt files│ ├── Harman IE 2019v2 Target.txt│ └── ...└── phone_book.json # unchangedMove every non-target FR file into
data/phones/, and every target file intodata/target/. Targets are usually easy to identify — they end inTarget.txt, or they appear by name in thetargetsarray of your old CrinGraph config.- Lab note: All files in your old flat
data/folder need to be sorted. Thedata/phone_book.jsonmoves as-is. - PublicGraphTool note: You have a partial split already —
data/targets/contains many of your target files. Mergedata/targets/*.txtand anydata/*Target.txtfiles at the root ofdata/into v2’sdata/target/. Everything else goes intodata/phones/. - Vanilla CrinGraph note: If you don’t already have a
phone_book.json, you’ll need to create one. See Managing Data for the schema and a minimal example.
- Lab note: All files in your old flat
-
Move Preference Bound files (PublicGraphTool only) — v2 expects bound data files at
data/Bounds U.txtanddata/Bounds D.txt(upper/lower). PublicGraphTool stored them atassets/pref_bounds/Bounds L.txtandBounds R.txt(left/right). Copy them over and rename:assets/pref_bounds/Bounds L.txt→data/Bounds U.txtassets/pref_bounds/Bounds R.txt→data/Bounds D.txt
Also make sure your compensation baseline (usually a KEMAR DF or similar) is present in
data/target/, and record its filename (without extension) — you’ll setPREFERENCE_BOUND.BASE_DF_TARGET_FILEto it in the next step. -
Generate a new
config.js— CrinGraph’s config format is incompatible with v2, so the cleanest approach is to build a fresh one using the Config Editor, referencing your old config for the values. A few common field mappings to speed you along:CrinGraph (old) modernGraphTool v2 (new) init_phones = [...]INITIAL_PHONES: [...]targets = [{ type, files }]TARGET_MANIFEST: [{ type, files }]DIR = "data/"PATH.PHONE_MEASUREMENT,PATH.TARGET_MEASUREMENT,PATH.PHONE_BOOKdefault_normalization = "Hz" / "dB"NORMALIZATION.TYPE("Hz"or"Avg")default_norm_hz = 500NORMALIZATION.HZ_VALUE: 500default_y_scale = "40db"VISUALIZATION.DEFAULT_Y_SCALE: 40watermark_text,watermark_image_urlWATERMARK: [{ TYPE, CONTENT, ... }]rig_descriptionVISUALIZATION.RIG_DESCRIPTIONlabelsPosition = "bottom-left"VISUALIZATION.LABEL.LOCATION: "BOTTOM_LEFT"headerLinks = [...]TOPBAR.LINK_LIST: [...]page_title,page_descriptionSet in index.html<title>/<meta>(step 6)themingEnabled,alt_layout,alt_*flagsNot needed — v2’s theme and layout are always on extraEQBands,extraEQpluginsNot needed — v2 has built-in Interactive EQ and Hardware EQ preference_bounds_dir,preference_bounds_namePREFERENCE_BOUND.BASE_DF_TARGET_FILE+ file location indata/tiltableTargets,compTargetsTARGET_CUSTOMIZER.CUSTOMIZABLE_TARGETSdefault_tilt,default_bass_shelf,default_ear,default_trebleTARGET_CUSTOMIZER.INITIAL_TARGET_FILTERSallowSquigDownload,analyticsEnabledSQUIGLINK.ENABLE_*fieldsdefault_DF_nameUsed as the name in PREFERENCE_BOUND.BASE_DF_TARGET_FILEFor the field-by-field reference of every v2 option, see Customizing the Page →
config.js. -
Generate a new
theme.css— use the Theme Generator to build a v2-compatible theme visually. You can eyeball the colors from your old stylesheets:- Lab: start from
styles/dark.css/styles/white.cssfor the dark/light palettes andstyle-alt-theme.cssfor accent colors. - PublicGraphTool:
assets/css/extra.cssholds most of the custom CSS variables (look for--accent-color-contrast,--background-color);dark.css/theme-*.csshold the rest. - Vanilla:
style.cssandstyle-alt.css.
Drop the generated
theme.cssalongside your newindex.htmlandconfig.js. - Lab: start from
-
Migrate page metadata (
index.html) — v2 ships with its ownindex.html; the edits you made to your CrinGraphindex.htmldo not carry over automatically. Re-apply them:<title>and<meta name="title">(CrinGraphpage_title)<meta name="description">(CrinGraphpage_description)- Open Graph tags:
<meta property="og:title">,<meta property="og:description">,<meta property="og:url">,<meta property="og:image"> <link rel="canonical">- Favicons:
<link rel="icon">,<link rel="shortcut icon">,<link rel="apple-touch-icon">— repoint these to your own image files (copy them intoassets/images/first) <meta name="apple-mobile-web-app-title">- Web app manifest:
<link rel="manifest">(if you have one)
The Customizing the Page → Changing Page Metadata section has the full field-by-field reference.
Things that should NOT be carried over from your CrinGraph
index.html:<script src="https://squig.link/squigsites.js"></script>— v2 has native squig.link integration. Enable it via theSQUIGLINKsection inconfig.jsinstead. Cross-site search, sponsor banner, and multi-GA4 analytics are all built in.<script src="assets/js/graphAnalytics.js"></script>— v2 analytics are routed throughSQUIGLINK.ANALYTICS_MEASUREMENT_IDS(an array, so multi-tag support works out of the box).<script src="assets/js/reinvented-color-wheel.min.js"></script>+reinvented-color-wheel.min.css— v2 has a built-in color picker on every curve’s color swatch.<audio id="pinkNoiseAudio">/<audio id="scarletFIRE">tags — not a v2 feature.<script src="assets/js/90inclusion.js"></script>— PublicGraphTool-specific; not applicable to v2.- Google Fonts
<link>tags for Open Sans / Source Sans Pro — v2 ships with the Pretendard Variable font by default. Keep them only if you’re intentionally replacing the font stack.
-
Delete CrinGraph-specific files — once steps 1–6 are complete, your old CrinGraph files are no longer needed in the v2 folder. Safe to remove:
graphtool.js,equalizer.js,listAugment.js,saveSvgAsPng.js,graphAnalytics.jsd3.v5.min.js,d3-selection-multi.v1.min.js,fuse.min.js,reinvented-color-wheel.min.jsstyle.css,style-alt.css,style-alt-theme.css,styles/(folder),extra.css, any CrinGraph-specific theme CSScringraph-favicon.png,cringraph-icon*.png,cringraph-logo.svg(keep your own branding images)90inclusion.js, audio asset files if they were only used by the old<audio>tagsdevicePEQ/plugin folder — v2 has built-in Hardware EQ- Old
config.js,config_hp.js,headphones.html,graph_*.html,iframe.html
Keep your
data/folder, your newconfig.js, your newtheme.css, your favicon/watermark images, and v2’s own files. -
Test locally and deploy.
Picking a Deployment Option
Section titled “Picking a Deployment Option”The Pre-built Release is closest to how you deploy CrinGraph today: download it, drop your data/, config.js and theme.css in, and upload. CDN deployment (recommended: the app bundle loads from jsDelivr and updates itself) and GitHub Pages (free hosting, if you’d rather stop running a web server) are the alternatives — Choosing a Deployment compares all four.
If you pick CDN mode, watch out for BASE_PATH
Section titled “If you pick CDN mode, watch out for BASE_PATH”In v2 CDN mode, any deployment not at the root of its (sub)domain requires CDN_MODE.BASE_PATH in config.js. Without it, the home page loads fine but every share link 404s. The fix is one config line. For a site at example.com/headphones/:
CDN_MODE: { MAJOR_VERSION: 2, BASE_PATH: "/headphones",},Full explanation and worked examples: Why BASE_PATH is almost always required.
This matters most for the headphone sibling deployment mentioned above — your earphone instance at the subdomain root doesn’t need BASE_PATH, but the headphone instance at /headphones/ does.
Already running CrinGraph alongside another tool?
Section titled “Already running CrinGraph alongside another tool?”If you want to keep CrinGraph as the primary front page and run modernGraphTool in a subfolder (or vice versa), the Dual-hosting guide walks through that layout end-to-end — including how to share a single data/ folder between both tools.