Caveats & sharp edges

Internal behaviors that surprise contributors — CLI parsing, caching, globs, HTML parsing assumptions, and provider ordering.

Caveats & sharp edges

These notes come straight from implementation details in packages/manic/src. They are not UX complaints — they are constraints you hit when extending Manic or debugging CI.


CLI & environment

TopicDetail
--port vs server.portcreateManicServer reads config.server.port from loadConfig(). manic dev / manic start also inject PORT into child env — custom ~manic.ts code must explicitly process.env.PORT if you expect CLI parity (CLI overview).
Ignored flagsmanic build and manic deploy parse --port / --network but drop them on the floor.
manic fmtDoes not forward argv — no --check shortcut today (Lint & format).
--versionPrints latest literal — rely on package.json / bun pm for semver truth (CLI overview).

Config caching

loadConfig() caches the merged config object for the lifetime of the process. manic dev watches manic.config.* by killing the Bun child and re-importing the config module for spawn metadata, but anything calling loadConfig() inside long-lived helpers assumes immutable config after first load.


Discovery & manifests

TopicDetail
~ prefixAny app/routes file/folder beginning with ~ is ignored for routing except ~404.tsx / ~500.tsx handling (Discovery).
Route groups(segment)/ folders are stripped from URLs during discoverRoutes().
writeRoutesManifest() during buildCalled without touch: true, so ~manic.ts is not auto-touched — unlike watchRoutes renames (discovery.ts).
API glob mismatchmanic build only bundles app/api/**/index.ts. tsx API entries won’t join the production graph unless renamed/adjusted (Bundler integration).

HTML & server bundle rewriting

Production server.js generation performs string replacement on ~manic.ts:

  • Expects an import … from './app/index.html' (or equivalent single-line shape) to rewrite into Bun.file(...).text().
  • Highly custom HTML import patterns may require adjusting build.ts logic — there is no plugin hook for this rewrite yet.

Plugin build context gaps

During plugin.build execution inside manic build:

  • apiRoutes is always [] — APIs are bundled after plugin hooks fire.
  • Plugins that need API paths must glob app/api themselves or run logic later inside provider.build.

Provider ordering vs comments

provider.build hooks execute after oxc-minify completes (despite an outdated inline comment claiming otherwise). Providers therefore see final byte sizes on disk — useful — but cannot influence minification settings mid-flight.


Lint parity

manic lint forces --config .oxlintrc.json. manic build shells oxlint . without that flag — ensure discovery picks up the same rules as CI (Lint & format).


Type system vs runtime

OXC transformSync strips types without tsc validation. Unsafe casts or unused imports might compile at transform time yet fail elsewhere — keep tsc in CI.


See also

On this page