Releases: arkstack-hq/arkstack
0.15.3
Edge tags: @vite, @inertia, @inertiaHead
Cleaner root templates — no more manual <script> wiring or {{{ ... }}}
interpolations for Inertia and Vite assets.
@arkstack/view — @vite(...)
A first-class Vite asset tag:
@vite('resources/js/app.ts')
@vite(['resources/css/app.css', 'resources/js/app.ts'])- Development: emits the Vite dev-server client + module scripts.
- Production: reads
public/build/.vite/manifest.jsonand emits the hashed<script>/<link>tags, including a chunk's imported CSS. Throws a clear error if the manifest or an entry is missing. - Configurable via
VITE_DEV_URL(dev server) and the exportedviteTags(entries, options)helper (hot/devUrl/manifest/buildDir). Registered on every view factory. - Register your own tags too:
view().tag(name, block, seekable, compile).
@arkstack/inertia — @inertia and @inertiaHead
The root template now reads:
<head>
@inertiaHead
@vite('resources/js/app.ts')
</head>
<body>
@inertia
</body>@inertia— the mount element (or server-rendered markup with SSR).@inertiaHead— SSR head tags (empty without SSR).
Both fall back to empty output when absent (no strayundefined), and the publishedapp.edgestub uses them out of the box.
Compatibility
Backward compatible: the adapter still passes inertia / inertiaHead data, so
existing templates using {{{ inertia }}} keep working.
Note: Edge tags are line-level — put
@inertia,@inertiaHead, and@vite(...)each on their own line.
Full Changelog: 0.15.1...0.15.3
0.15.1
What's New
ark dev — local network & HTTPS
The development server gains two flags for testing on real devices and over
secure connections.
Highlights
--hostexpose the dev server on your local network. The dev server
now binds127.0.0.1by default (local-only);--hostswitches it to
0.0.0.0and prints the detected LAN URL alongside the local one, so you can
open the app from your phone or another machine.--s|secureserves the dev server over HTTPS using an auto-generated,
in-memory self-signed certificate (no setup; browsers show the usual
self-signed warning).- Both compose with the existing
--t|tunnel(Ngrok) flag.
Examples
ark dev # http://127.0.0.1:3000 (local only)
ark dev --host # + Network: http://192.168.1.20:3000
ark dev --secure # https://127.0.0.1:3000 (self-signed)
ark dev --host --secure # HTTPS, exposed on the LANFull Changelog: 0.15.0...0.15.1
0.15.0
What's New
@arkstack/inertia — Server-side rendering
The Inertia adapter now supports SSR, so the initial page load is fully
rendered HTML (great for first paint and crawlers) and the client hydrates it.
Subsequent Inertia visits stay client-side.
Highlights
- SSR rendering — when
ssr.enabled, the initial visit is rendered by an
external Node SSR server (your built SSR bundle); the markup and head tags are
embedded in the response. If the SSR server is unreachable, the adapter falls
back to client-side rendering, so SSR can never take a request down. ark inertia:ssr— a new command that runs and supervises the SSR bundle,
restarting it if it crashes (--bundle <path>,--no-restart). Auto-discovered
like other package commands.Inertia.configure({ ... })— override Inertia config at runtime (e.g.
enable SSR programmatically); handy for tests and custom setups.- New config —
ssr.url(render endpoint, defaulthttp://127.0.0.1:13714/render)
andssr.bundle(defaultdist-ssr/ssr.js). - Exports —
renderViaSsr(),superviseProcess(),resolveSsrBundle(),
DEFAULT_SSR_URL,DEFAULT_SSR_BUNDLE, plusSsrResponse/SuperviseOptionstypes.
Setup
- Add an SSR entry (
src/ssr.ts) using your client adapter's server renderer. - Build it:
vite build --ssr src/ssr.ts --outDir dist-ssr. - Run it:
ark inertia:ssr. - Enable it: set
ssr.enabled(orINERTIA_SSR=true) insrc/config/inertia.ts.
Verified
SSR shipped with 8 unit tests (markup/head injection, fallbacks) plus a real
browser E2E (Vue 3 SSR server + hydration, no full reload). The inertia:ssr
command adds 8 more tests — real-process restart/stop/failure coverage — and a
smoke test supervising the live SSR bundle (health → crash → restart → health →
clean stop).
See the Inertia guide.
Full Changelog: 0.14.22...0.15.0
0.14.22
What's new
Custom error response bodies (@arkstack/common)
AppException (and any subclass) can now define a body property that is merged
into the serialized error payload. This lets you extend the framework's standard
error shape — { status, code, message, errors?, stack? } — with your own fields,
or override the defaults entirely.
import { AppException } from '@arkstack/common'
class PaymentException extends AppException {
body = { error_code: 'PAYMENT_FAILED', retryable: true }
}
throw new PaymentException('Payment failed', 402)
// → { status: 'error', code: 402, message: 'Payment failed',
// error_code: 'PAYMENT_FAILED', retryable: true }
**Full Changelog**: https://github.com/arkstack-hq/arkstack/compare/0.14.19...0.14.220.14.19: fix(common): fall back to the alternate build output when loading config
What's Changed
Features
- Typed
env()return values. Added an augmentableEnvRegistryinterface mapping known environment variables to their coerced types, withenv()(andEnvLoader.get()) inferring returns from it:- Known keys infer their type,
env('APP_PORT')→number,env('NODE_ENV')→'development' | 'production' | 'test',env('MAIL_SECURE')→boolean. - Unknown keys fall back to
string; a provided default is unioned into the result. - An explicit value type still wins (
env<boolean>('FLAG')), and applications can extendEnvRegistryvia declaration merging. - New exported helper types:
EnvRegistry,EnvKey,EnvLookup,EnvReturn.
- Known keys infer their type,
- Auto-generated env types.
prepare/build now generates anEnvRegistryaugmentation from the application's.env.example(falling back to.env) into.arkstack/ark.d.ts, mirroring config-interface generation. Each variable's type is inferred (number / boolean / string), and framework-owned keys are skipped so the generated declaration never conflicts with the curated baseline, your app-specific variables get types automatically. Exposed viaBuildInterfaces.env()and the pureBuildInterfaces.envRegistryFromEnv().
Fixes
- Environment loading is no longer import-order dependent.
.envis now loaded lazily on the firstenv()read instead of relying on a side-effectimport 'dotenv/config'. Linters/bundlers that reorder imports could previously place an env-reading module before dotenv populatedprocess.env, leaving it with default/stale values. (dotenv is loaded with{ quiet: true }and never overrides already-set variables.) - No duplicate
export {}in generated.arkstack/ark.d.ts. The env-registry block no longer emits its own module marker; the generator ensures the combined declaration file has exactly one.
Refactor
EnvLoaderandConfigLoaderclasses. Environment and configuration handling were extracted fromsystem.tsinto dedicatedEnvLoaderandConfigLoaderclasses (new exports, with sharedenvLoader/configLoadersingletons).env()andconfig()now delegate to these instances; their call signatures and return values are unchanged.- Dropped now-redundant explicit generics at call sites that pass a default (
NODE_ENV,TUNNEL,SESSION_LIFETIME) so they infer fromEnvRegistry, and coercedappUrl's numeric port forurl.port.
Internal
- Added
dotenvas a direct dependency of@arkstack/common. - New tests:
EnvLoadercoercion and the env-registry generator.
Full Changelog: 0.14.17...0.14.19
0.14.17
What's Changed
Features
- Production module resolution. Application modules — models, route groups, and console commands — now resolve from the compiled build output (
dist) in production and from TypeScript source in development. A production deploy can ship onlydist(nosrc); the build strips the leadingsrc/segment (src/app/models/User.ts→dist/app/models/User.js) and the framework remaps paths accordingly.- New
@arkstack/commonhelpers:resolveRuntimeModule(sourcePath)— resolves a source module path to an importable file (source in dev, compiled output in prod), choosing the correct extension.resolveRuntimeDir(sourcePath)— directory counterpart of the above, for resolving source directories (e.g.src/routes) to their runtime location.toOutputPath(sourcePath)— pure path transform mapping a source path to its build-output counterpart.
getModel(), console command discovery, and the Express/H3 route-group loaders now use these resolvers, fixing failures in production deploys that previously reached forsrc/files at runtime.
- New
Docs
- New Deployment guide covering build output,
NODE_ENV, output directories, and the runtime resolution helpers.
Requires
NODE_ENV=productionin production (the same assumption the config loader already makes).
Full Changelog: 0.14.16...0.14.17
0.14.16
What's Changed
Fixes
- Production module resolution. The framework no longer reaches for
src/files at runtime in production. Models, console commands, and route groups now resolve from the build output (dist) when running compiled, falling back to source in development. Previously a production deploy that shipped onlydistcould fail to load models (getModel) and route groups because the loaders importedsrc/...paths directly, even though the build strips thesrc/segment (src/app/models/User.ts→dist/app/models/User.js).- New
resolveRuntimeModule()/toOutputPath()helpers in@arkstack/commonmap a source path to its compiled counterpart and pick the right file per environment (production prefersdist, development prefers source). getModel()resolves the configured model path through the new resolver.discoverCommands()orders its candidate directories by environment instead of always preferringsrc.- The Express and H3 drivers resolve
routes/apiandroutes/webroute groups through the resolver instead of joiningsrc/routes/*directly.
- New
Note: this relies on
NODE_ENV=productionbeing set in production (the same assumption the config loader already makes).
Full Changelog: 0.14.15...0.14.16
0.14.15
What's Changed
- Replace the --ignore flag with the global --no-interation flag KeyGenerateCommand
Full Changelog: 0.14.14...0.14.15
0.14.14
What's Changed
- Add
--ignoreoption to silently skip app key generation in KeyGenerateCommand
Full Changelog: 0.14.3...0.14.14
0.14.3
What's Changed
- Add
tunneloption to theark devcommand to tunnel all app traffic through Ngrok. - Attach tunnel url to
globalThisobject andprocess.env.
Full Changelog: 0.14.1...0.14.3