Skip to main content
Version: v2

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.

Looking for the highlights?

For a feature-level overview of what v2 brings to the table, see What's New in v2 — especially useful if you're deciding whether to migrate at all.

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 CrinGraphsquiglink labPublicGraphTool
Config fileconfig.js (root)config.js (root), config_hp.js for HP variantassets/js/config.js
Phone FR filesdata/*.txt (flat)data/*.txt (flat)data/*.txt (flat)
Target filesdata/*.txt (mixed with phones)data/*.txt (mixed with phones)Split: some in data/*Target.txt, more in data/targets/
phone_book.jsonOptional (often absent)data/phone_book.jsondata/phone_book.json
Preference boundsNoneNoneassets/pref_bounds/Bounds L.txt + Bounds R.txt
Theme CSSstyle*.css at rootstyle*.css + styles/dark.css + styles/white.cssassets/css/extra.css + style*.css
Headphones variantUsually a separate installdata_hp/ folder + config_hp.jsdata_hp/ folder + headphones.html + config_hp.js
External scriptsNoneNonesquigsites.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

Format-compatible, carries over unchanged:

  • FR measurement .txt files (tab/space-separated freq dB columns)
  • Target .txt files (same format)
  • phone_book.json schema (see Managing Data if you need to create one)
  • Watermark images, logos, favicon images

Not compatible, needs regeneration:

  • config.js — CrinGraph uses top-level const bindings (const init_phones = [...], DIR = "data/"); v2 uses a single structured CONFIG = { ... } 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.css with CSS custom properties (OKLCH-based).
  • Folder layout — CrinGraph keeps phones and targets mixed in a single data/ folder; v2 expects them split into data/phones/ and data/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 the SQUIGLINK config section. Remove the script tag.

Migration Steps

  1. Download the latest modernGraphTool v2 release and extract it.

  2. 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 # unchanged

    Move every non-target FR file into data/phones/, and every target file into data/target/. Targets are usually easy to identify — they end in Target.txt, or they appear by name in the targets array of your old CrinGraph config.

    • Lab note: All files in your old flat data/ folder need to be sorted. The data/phone_book.json moves as-is.
    • PublicGraphTool note: You have a partial split already — data/targets/ contains many of your target files. Merge data/targets/*.txt and any data/*Target.txt files at the root of data/ into v2's data/target/. Everything else goes into data/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.
  3. Move Preference Bound files (PublicGraphTool only) — v2 expects bound data files at data/Bounds U.txt and data/Bounds D.txt (upper/lower). PublicGraphTool stored them at assets/pref_bounds/Bounds L.txt and Bounds R.txt (left/right). Copy them over and rename:

    • assets/pref_bounds/Bounds L.txtdata/Bounds U.txt
    • assets/pref_bounds/Bounds R.txtdata/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 set PREFERENCE_BOUND.BASE_DF_TARGET_FILE to it in the next step.

  4. 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_BOOK
    default_normalization = "Hz" / "dB"NORMALIZATION.TYPE ("Hz" or "Avg")
    default_norm_hz = 500NORMALIZATION.HZ_VALUE: 500
    default_y_scale = "40db"VISUALIZATION.DEFAULT_Y_SCALE: 40
    watermark_text, watermark_image_urlWATERMARK: [{ TYPE, CONTENT, ... }]
    rig_descriptionVISUALIZATION.RIG_DESCRIPTION
    labelsPosition = "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 Device PEQ
    preference_bounds_dir, preference_bounds_namePREFERENCE_BOUND.BASE_DF_TARGET_FILE + file location in data/
    tiltableTargets, compTargetsTARGET_CUSTOMIZER.CUSTOMIZABLE_TARGETS
    default_tilt, default_bass_shelf, default_ear, default_trebleTARGET_CUSTOMIZER.INITIAL_TARGET_FILTERS
    allowSquigDownload, analyticsEnabledSQUIGLINK.ENABLE_* fields
    default_DF_nameUsed as the name in PREFERENCE_BOUND.BASE_DF_TARGET_FILE

    For the field-by-field reference of every v2 option, see Customizing the Page → config.js.

  5. 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.css for the dark/light palettes and style-alt-theme.css for accent colors.
    • PublicGraphTool: assets/css/extra.css holds most of the custom CSS variables (look for --accent-color-contrast, --background-color); dark.css / theme-*.css hold the rest.
    • Vanilla: style.css and style-alt.css.

    Drop the generated theme.css alongside your new index.html and config.js.

  6. Migrate page metadata (index.html) — v2 ships with its own index.html; the edits you made to your CrinGraph index.html do not carry over automatically. Re-apply them:

    • <title> and <meta name="title"> (CrinGraph page_title)
    • <meta name="description"> (CrinGraph page_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 into assets/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 the SQUIGLINK section in config.js instead. Cross-site search, sponsor banner, and multi-GA4 analytics are all built in.
    • <script src="assets/js/graphAnalytics.js"></script> — v2 analytics are routed through SQUIGLINK.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.
    Source builders

    If you build from source, edit src/app.html instead of index.html. The output dist/index.html is generated from that template.

  7. 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.js
    • d3.v5.min.js, d3-selection-multi.v1.min.js, fuse.min.js, reinvented-color-wheel.min.js
    • style.css, style-alt.css, style-alt-theme.css, styles/ (folder), extra.css, any CrinGraph-specific theme CSS
    • cringraph-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> tags
    • devicePEQ/ plugin folder — v2 has built-in Device PEQ
    • Old config.js, config_hp.js, headphones.html, graph_*.html, iframe.html

    Keep your data/ folder, your new config.js, your new theme.css, your favicon/watermark images, and v2's own files.

  8. Test locally and deploy.

Why there's no headphones.html in v2

PublicGraphTool ships a dual-instance layout with headphones.html + data_hp/ + config_hp.js, and squiglink lab has a similar config_hp.js + data_hp/ pattern. modernGraphTool v2 intentionally does not reproduce this.

The squig.link service model hosts earphone and headphone databases as separate sibling directories on the same (sub)domain — e.g. username.squig.link/ for earphones and username.squig.link/headphones/ for headphones — each one a standalone deployment with its own data/, config.js, and theme.css. This keeps each instance single-purpose and simpler to reason about, and it's how squig.link service expects deployments to be structured for features like cross-instance search and unified analytics.

If you're migrating from a dual-instance CrinGraph setup, treat it as two separate migrations: one earphone deployment and one headphone deployment, each following the steps on this page independently. For the headphone instance in a subdirectory, see the BASE_PATH note below.

Picking a Deployment Option

modernGraphTool v2 offers three deployment paths:

  • Pre-built Release — Closest to how you deploy CrinGraph today. Download the release, drop your data/, config.js, and theme.css in, upload. No BASE_PATH to worry about.
  • CDN Deployment — Recommended, and a thinner drop: only your index.html, config.js, theme.css, data/, and assets/ live on your server; the app bundle loads from jsDelivr and auto-updates with new v2 releases.
  • Building from Source — For developers and forks.
CDN Alternative

Instead of hosting the full pre-built release, consider the CDN deployment mode. You don't need to manage the app code, and future updates apply automatically with it.

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?

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.