@vyriy/static
v0.8.9
Published
Static file and SPA serving helpers for Vyriy servers.
Readme
@vyriy/static
Part of Vyriy - a calm architecture toolkit for TypeScript, React, SSR, SSG, APIs, and cloud-ready apps.
Full documentation: https://vyriy.dev/docs/static/
Static file and SPA serving CLI with reusable Lambda-style handlers and router helpers.
CLI
Install globally:
npm install --global @vyriy/staticServe a static directory:
vyriy-static
vyriy-static dist
vyriy-static public --cache static
vyriy-static --port 3000 dist
vyriy-static dist --spa --fallback index.html --cache staticWhen no directory is provided to the CLI, it tries dist, build, public, out, and then the current directory.
CLI flags:
--port <port>or-p <port>sets the local server port.--cache <preset>setsnone,default,static, orimmutable.--index <file>sets the static directory index file.--not-found <file>sets the static404response file.--spaenables SPA fallback mode.--fallback <file>sets the SPA fallback file.--helpor-hprints command help.--versionor-vprints the package version.
CLI option priority is explicit CLI args, then VYRIY_STATIC_* env variables, then defaults. Outside production, CLI serving defaults to cache: 'none' when --cache is omitted.
API
Install as a project dependency:
npm install @vyriy/staticUse direct handlers:
import { useSpa, useStatic } from '@vyriy/static';
export const assets = useStatic('./public', {
cache: 'immutable',
index: false,
});
export const site = useStatic('./dist', {
cache: 'static',
index: 'index.html',
notFound: '404.html',
});
export const app = useSpa('./dist', {
cache: 'static',
fallback: 'index.html',
});Use router helpers:
import { createRouter } from '@vyriy/router';
import { withStatic } from '@vyriy/static';
export const router = withStatic(createRouter())
.get('/api/health', () => ({ body: JSON.stringify({ ok: true }) }))
.static('/assets', './dist/assets', { cache: 'immutable' })
.spa('/app', './dist', { cache: 'static' })
.fallbackSpa('./landing-dist', { cache: 'static' });static and spa mounts strip the route prefix before resolving files:
/assets/logo.svg -> ./dist/assets/logo.svg
/app/assets/main.js -> ./dist/assets/main.jsGlobal fallbacks are explicit:
fallback(handler)registers a custom unmatched-request handler.fallbackStatic(directory, options?)serves unmatched requests through static file behavior.fallbackSpa(directory, options?)serves unmatched requests through SPA fallback behavior.
Only one fallback can be registered on a wrapped router.
Cache
Cache presets:
falseor'none'sendsCache-Control: no-store.'default'sendspublic, max-age=3600with validators.'immutable'sendspublic, max-age=31536000, immutablewith validators.'static'caches assets long-term and revalidates HTML and metadata.
The static preset is designed for S3/CloudFront, Storybook, SPA builds, MFE assets, and static sites:
assets -> long immutable cache
html/json/xml/txt/yml -> no-cache + ETag + Last-Modified
SPA fallback index.html -> no-cache + ETag + Last-ModifiedDefaults:
useStatic('./dist')usesindex: 'index.html',notFound: false, andcache: 'default'.useSpa('./dist')usesfallback: 'index.html'andcache: 'static'.staticServer()triesdist,build,public,out, and then the current directory.
