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
| Topic | Detail |
|---|---|
--port vs server.port | createManicServer 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 flags | manic build and manic deploy parse --port / --network but drop them on the floor. |
manic fmt | Does not forward argv — no --check shortcut today (Lint & format). |
--version | Prints 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
| Topic | Detail |
|---|---|
~ prefix | Any 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 build | Called without touch: true, so ~manic.ts is not auto-touched — unlike watchRoutes renames (discovery.ts). |
| API glob mismatch | manic 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 intoBun.file(...).text(). - Highly custom HTML import patterns may require adjusting
build.tslogic — there is no plugin hook for this rewrite yet.
Plugin build context gaps
During plugin.build execution inside manic build:
apiRoutesis always[]— APIs are bundled after plugin hooks fire.- Plugins that need API paths must glob
app/apithemselves or run logic later insideprovider.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
- Build pipeline — ordering truth table
- Performance model — what speed claims exclude
- Manic internals (advanced) — config + manifest companion doc