Automation & Agents

Turn Hardcoded Options into Self-Serve: A Registry Refactor Checklist

What locks you in is usually not a missing button. It's that the options live in code instead of data. Turn them into data, and adding an option goes from an engineer's job to one click by the user.

10/04/2026 | 3 min read | Works in any language or framework — about a 15-minute read

The one idea that matters

A feature is “engineer-only” not because it lacks a button, but because its options are hardcoded as code instead of stored as data.

  • Hardcoded options = a fixed list in source code (a dict, array or enum). Changing it means editing code and redeploying.
  • Data-driven options = content stored in a file or database. Changing it means editing that data; the code stays put.

Moving from the first to the second is the registry pattern.

Step 1 | Find the hardcoded list

Look for a fixed set of options baked into the source, something like:

OPTIONS = {
  "option_a": config_a,
  "option_b": config_b,
}

That’s what ties both you and your users down.

Step 2 | Move it into an external JSON registry

{
  "items": {
    "option_a": { "name": "Display name A", "config": "..." },
    "option_b": { "name": "Display name B", "config": "..." }
  }
}

Have the code read this JSON instead of the hardcoded list. Because the file lives on disk, its contents survive a restart. That’s what “persistent” means here.

Step 3 | Add a “create” endpoint

The backend API always has four stages:

  1. Receive: accept the user’s form fields or uploaded file.
  2. Process: validate, convert, clean — whatever your domain needs.
  3. Register: read the registry → add one entry → write it back.
  4. Feedback: return a preview right away so the user can confirm the new entry works.

Step 4 | Serve “built-in + registry” as one list

The API that returns the option list now merges built-in options with user-added registry entries. The frontend dropdown picks up the new items automatically.

Step 5 | Add a “delete” endpoint

If users can add, they need to remove: drop the entry from the registry and delete its associated files. Block deletion of built-in options — those are code, not user data.

Step 6 | Wire up “upload → name → confirm” in the frontend

One card or form: pick content → name it → submit → show progress → refresh the list when done and select the new item.

Three traps you will hit

Trap 1: User-added items take a different code path than built-ins. Preview runs path A, production runs path B, so the preview looks fine and production breaks. Fix: route user-added items through exactly the same processing function as built-ins, so the preview is a smaller version of the real output.

Trap 2: Committing user data to git. registry.json is runtime data that changes with every user action and may contain local paths. Add it to .gitignore: code goes into version control, data stays on each machine.

Trap 3: The frontend changed, but users still see the old page. If your UI is built into static files served by the backend, you must rebuild after changes, and any tab already open is still the old version — hard refresh it (Ctrl/Cmd+Shift+R). Many “the feature didn’t work” bugs are just this. A small bonus trap: for file pickers, a button plus a hidden file input clicked from code is more reliable than wrapping a hidden input in a label, which can leave clicks doing nothing.

Verification: don’t trust “the code looks right”

Pass three layers, each producing a real result:

  1. Module level: call the create/read/delete functions directly for a full roundtrip.
  2. API level: send a real upload request and confirm the backend produces a real artifact.
  3. Real usage: open a browser and click through “upload → add → confirm → delete” with a mouse.

Every layer must show an actual file or actual response, not “it should work.”

When you get stuck, ask AI

I’m a beginner building a feature with <your language/framework, e.g. Python FastAPI + React>. I want to turn a list of options hardcoded in my source into a registry that users can add to from the web page and that persists after restarts. Here’s the hardcoded part: <paste the code>. Walk me through step by step: 1) how to move it into a JSON file and load it at startup; 2) how to add “create” and “delete” API endpoints; 3) how the frontend uploads and refreshes the list when done. The error I’m seeing is: <paste the full error text>. Explain the cause first, then give me a minimal runnable example I can copy.

The one-line takeaway

Next time you’re about to add one more hardcoded option, ask: should this become data users can add and remove themselves? If yes, and it’ll happen more than once, pull it into a registry.

Support this work:Support on Ko-fi