Skip to content

Local Side-by-Side Workflow

The local side-by-side workflow uses npm link to point the consumer’s node_modules/@arda-cards/design-system at a sibling worktree of ux-prototype. Edits in ux-prototype (with watch-mode build) are immediately visible in the consumer’s dev server. No publish, no version bump, no PR per iteration.

This is the highest-velocity workflow for two-sided changes — and the lowest-fidelity, because the consumer’s CI never tests against the linked build. Use it for rapid prototyping; switch to preview publish or coordinated multi-PR before submitting work for review.

  • You’re actively editing both repos in a single mental session.
  • You need sub-second feedback on design-system changes inside the consumer.
  • You will not push consumer code that depends on un-published design-system code.

The script expects sibling directories at the workspace level:

arda/
├── ux-prototype/ # or a worktree of it
├── api-proxy/ # or a worktree
└── arda-frontend-app/ # or a worktree

Worktrees of all three are fine — and recommended when working on multiple projects concurrently.

  1. Run the link script:
    Terminal window
    npm run dev:local
    # or: bash tools/dev-local.sh [port]
    The script (arda-frontend-app/tools/dev-local.sh):
    • Performs an initial build of ../ux-prototype and ../api-proxy.
    • Starts watch-mode rebuilds of both packages in the background.
    • npm links both packages into arda-frontend-app/node_modules/@arda-cards/*.
    • Starts the Next.js dev server.
    • Registers a trap so that on clean exit (Ctrl+C, normal termination), npm install runs to restore dependencies from the registry.
  2. Edit code in either repo. Watch-mode rebuilds the design-system; the dev server hot-reloads.
  3. Stop the dev server (Ctrl+C). The trap runs npm install, restoring the registry-published dependency.

To check whether node_modules is currently linked to a local build:

Terminal window
ls -la node_modules/@arda-cards/design-system | head -1

A lrwxr-xr-x (symlink) line means linked. A drwxr-xr-x (directory) means installed from registry.

The trap-based cleanup runs on EXIT for normal termination, but kill -9 and process crashes bypass it. After such an event, manually restore:

Terminal window
npm install --no-audit --prefer-offline

This removes the symlinks and reinstalls from the registry.

When local development is done and you’re ready to push:

  1. Stop the dev server cleanly so the trap restores node_modules (or run npm install manually).
  2. Verify symlinks are gone (ls -la node_modules/@arda-cards/).
  3. Choose the publish path:
  4. Sequence the merges correctly:
    • Stable design-system release must merge first, then consumer PR bumps to the new stable.
    • Or: design-system preview publishes first, consumer PR uses the preview, design-system merges to stable, consumer PR swaps preview → stable, consumer merges.
  • Lockfile must match registry state at push time. Never push a consumer commit while symlinks are active — package-lock.json won’t reflect what’s actually being used.
  • Local builds may behave differently from published builds. Examples: LIB_BUILD=true flag effects, vite-plugin-dts output, asset-copy behavior. Run a final pass against the published artifact (preview publish) before merging anything cross-repo.
  • No CI sees the linked state. Bugs that only manifest in the linked build will only be caught manually.
ProCon
Sub-second iteration cycleLockfile is meaningless during the session — must restore before push
No publish overhead per changeCI never validates the linked combination
Both repos editable in real timekill -9 or crash leaves node_modules in an inconsistent state
Free — no token, no registry trafficPer-developer setup; not shareable