@marianmeres/sveltekit-adapter-demino
v1.5.0
Published
[](https://www.npmjs.com/package/@marianmeres/sveltekit-adapter-demino) [](https://jsr.io/@marianmeres/sveltekit-a
Readme
@marianmeres/sveltekit-adapter-demino
A SvelteKit adapter that outputs a Web-standard handler(req, info) function
compatible with @marianmeres/demino and
any Deno.ServeHandler-based server.
Install
Install the adapter as an npm dev dependency in your SvelteKit project:
npm install -D @marianmeres/sveltekit-adapter-deminoThe adapter runs at build time inside Vite/Node.js. It is not installed via
deno add— Deno only runs the generatedhandler.jsat serve time.
Configure
// svelte.config.js
import adapter from '@marianmeres/sveltekit-adapter-demino';
export default {
kit: {
adapter: adapter({
out: 'build', // default
// Cache-Control headers for disk-served static responses.
// All values below are defaults — override or set to `false` to disable.
cacheControl: {
immutable: 'public, immutable, max-age=31536000', // /_app/immutable/*
prerendered: 'public, max-age=600, stale-while-revalidate=86400', // prerendered pages
assets: 'public, max-age=86400', // unhashed static files
},
}),
},
};Note: SSR responses are not affected by these settings — use SvelteKit's
handlehook inhooks.server.tsto control caching for server-rendered routes.
Build
vite buildOutput structure:
build/
├── handler.js <- import this in your Deno server
├── client/ <- static assets + prerendered HTML (served automatically)
└── server/ <- SvelteKit SSR runtime (used internally by handler.js)Usage in your Deno server
import { demino, deminoCompose } from 'jsr:@marianmeres/demino';
import { handler as skHandler } from './build/handler.js';
const api = demino('/api');
api.get('/hello', () => ({ hello: 'world' }));
// SvelteKit handles everything that the API doesn't
const sk = demino();
sk.all('/*', skHandler);
Deno.serve(deminoCompose([api, sk]));Or if SvelteKit is your only app:
import { handler } from './build/handler.js';
Deno.serve(handler);How it works
The generated handler.js:
Prerendered redirects -- handles trailing-slash normalization (308 redirects) for prerendered pages, based on your SvelteKit
trailingSlashconfig.Static files & prerendered HTML -- served from
build/client/using@std/http/file-server'sserveDir. This covers everything in yourstatic/folder, compiled JS/CSS (/_app/...), and prerendered pages. Each response gets aCache-Controlheader based on its category:| Category | Path pattern | Default header | |----------|-------------|----------------| | Immutable |
/_app/immutable/*|public, immutable, max-age=31536000| | Prerendered | Pages from SvelteKit's prerender list |public, max-age=600, stale-while-revalidate=86400| | Static assets | Everything else (favicon, fonts, images…) |public, max-age=86400|Override any value via
cacheControlin adapter options, or set tofalseto skip setting the header for that category.Everything else -- forwarded to SvelteKit's SSR engine via
server.respond(). This handles server routes, SSR pages, and API endpoints defined inside your SvelteKit app.Asset reading -- the handler provides a
read()function to SvelteKit's server, enablingimport { read } from '$app/server'for runtime asset access.
Notes
Deno permissions needed at runtime:
--allow-net,--allow-read,--allow-envThe
platformobject available in SvelteKit hooks/endpoints will contain{ info: Deno.ServeHandlerInfo }, giving you access toremoteAddretc.The adapter runs in Node.js at build time (it's a Vite plugin). The generated
handler.jsruns in Deno at serve time.Your Deno server needs an import map for the npm packages that SvelteKit's SSR bundle references at runtime. The adapter emits
build/deno-imports.jsonlisting every bare specifier it found, each pinned to the version installed in yournode_modules. Point yourdeno.jsonat it:// deno.json { "importMap": "./build/deno-imports.json" }Or copy its
importsblock into your existingdeno.jsonimports. The file is regenerated on every build and keys are sorted alphabetically, so diffs stay clean.Disable emission with
adapter({ denoImports: false }), or refine viaadapter({ denoImports: { versionPrefix: "exact", exclude: ["tailwind-merge"], extraSpecifiers: ["some-dynamic-pkg"] } }).Caveats:
- Dynamic
import(someVar)with a computed string is invisible to any static scanner — useextraSpecifiersto force-add those entries. - A package whose
exportsdoesn't list a subpath the SSR bundle actually imports will still error at runtime; no import map can work around that.
Minimal manual fallback if you skip the generated file entirely:
{ "imports": { "@sveltejs/kit": "npm:@sveltejs/kit@^2.0.0" } }- Dynamic
