Validation
Every error carries a stable code and a fix hint.
The compiler validates every file before generating code. Every error carries a stable code and a fix hint, so failures are unambiguous:
| Code | What is rejected |
|---|---|
STATEMENT_OUT_OF_ORDER | Signals declared after handlers, or a return before other statements. |
FILENAME_MISMATCH | Component name does not match the file name - counter.tsx exporting Counter. |
MISSING_RUNSON / DUPLICATE_RUNSON | A file without a // @runsOn directive, or with more than one. |
PROP_UNWRAPPED_SIGNAL | A bare signal passed where a reactive value was expected. |
CLIENT_DATA_CALL | data() used in a @runsOn client file. |
CLIENT_ENV_ACCESS / CLIENT_SESSION_ACCESS | env() or session() used in a @runsOn client file - secrets never reach client bundles. |
CLIENT_IMPORTS_SERVER | A client file importing a server component - server modules are never publicly served. |
SERVER_SIGNAL / SERVER_EVENT_HANDLER | Signals or event handlers in a @runsOn server file - server output is static HTML. |
API_DATA_CALL / MIDDLEWARE_DATA_CALL | data() in an API route or middleware - it is page-render-time fetching. |
API_DUPLICATE_HANDLER | The same HTTP method exported twice from an API file. |
RUNTIME_NAME_COLLISION | A user binding shadowing an emitted runtime name (session, env, middleware, ...). |
MIDDLEWARE_RESULT / MIDDLEWARE_HELPER_NOT_RETURNED | A middleware returning anything other than next(), redirect(), or respond() - or a gate result that is not the return value. |
CHILDREN_ATTRIBUTE / UNEXPECTED_CHILDREN | children passed as an attribute, or nested JSX passed to a component without a declared children prop. |
INVALID_CSS_IMPORT | Any import from a .css file other than the bare side-effect form - or a CSS import in a @runsOn server file. |
UNSUPPORTED_EXPRESSION | Type assertions or other TS-only expressions in component code. |
Warnings (build continues)
Not every signal is an error. These print during the build and do not stop it:
| Code | What is flagged |
|---|---|
CSS_CLASS_COLLISION | The same class name defined in two stylesheets imported by the same page - name collision risk made visible. |
ENV_LEAK_TO_CLIENT_PROP | An env() result passed into a client:hydrate prop expression. |
SERVER_PAGE_ENV_PRERENDER | A static server page (no data()) reading env() - the value can end up in public HTML. |
Hard-rejected patterns
Beyond error codes, these patterns are hard-rejected:
- Any hook from React, Preact, or similar - imports are rejected outright.
- Global mutable state - any top-level
letused as shared state. - Context/Provider/DI patterns - state flows only through props.
- Default exports, multiple components per file, destructured props,
any-typed props. &&conditional rendering and inline.map()in JSX.
Run it yourself:
marisjs validate ./src/App.tsx checks a single file against every rule in this spec - useful in CI as a pre-commit gate that is faster than a full build.