• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
nbbaier

nbbaier

vt-hono-server-static

A Val Town adapter for Hono's serveStatic middleware
Public
Like
vt-hono-server-static
Home
Code
3
test
2
README.md
main.ts
Connections
Environment variables
Branches
1
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
…
Viewing readonly version of main branch: v18
View latest version
README.md

vt-hono-server-static

A Val Town adapter for Hono's serveStatic middleware. Lets you use the standard Hono serveStatic API — the same one used on Deno, Bun, Node, and Cloudflare Workers — to serve static files from your val's project files.

Why?

Hono's built-in serveStatic middleware requires filesystem access (Deno.open, node:fs, etc.), which Val Town doesn't provide. The existing std/utils provides staticHTTPServer() and serveFile(), but these don't integrate with Hono's middleware system.

This adapter bridges that gap — you get the full serveStatic API (root, path, rewriteRequestPath, onFound, onNotFound, mimes, etc.) working natively on Val Town.

Usage

import { Hono } from "npm:hono@4"; import { serveStatic } from "https://esm.town/v/nbbaier/vt-hono-server-static/main.ts"; const app = new Hono(); // Serve files under /static/* from the project root app.use("/static/*", serveStatic({ root: "./" })); // Serve a specific file at a fixed path app.use("/favicon.ico", serveStatic({ path: "./favicon.ico" })); // Rewrite request paths (e.g., /assets/* → /frontend/*) app.use("/assets/*", serveStatic({ root: "./", rewriteRequestPath: (path) => path.replace(/^\/assets/, "/frontend"), })); // Callbacks for cache headers or debugging app.use("/static/*", serveStatic({ root: "./", onFound: (path, c) => { c.header("Cache-Control", "public, max-age=3600"); }, onNotFound: (path, c) => { console.log(`${path} not found, requested ${c.req.path}`); }, })); app.onError((err) => Promise.reject(err)); export default app.fetch;

Options

All standard Hono ServeStaticOptions are supported:

OptionTypeDescription
rootstringRoot directory for file resolution (e.g., "./", "./frontend")
pathstringServe a specific file regardless of request path
rewriteRequestPath(path: string) => stringTransform the request path before file lookup
mimesRecord<string, string>Additional MIME type mappings
onFound(path: string, c: Context) => voidCalled when a file is found
onNotFound(path: string, c: Context) => voidCalled when a file is not found
precompressedbooleanCheck for .br/.gz variants (no-op on Val Town)

Plus one Val Town-specific option:

OptionTypeDescription
metaImportUrlstringOverride import.meta.url for resolving files from a different val

How It Works

Rendering mermaid diagram...

This adapter provides three platform-specific hooks to Hono's base serveStatic:

  • getContent(path) — Fetches file content from your val via esm.town using std/utils. TypeScript/TSX/JSX files are automatically transpiled to JavaScript.
  • isDir(path) — Heuristic check (paths without a file extension are treated as directories, triggering index.html fallback).
  • join(...paths) — Simple URL-style path concatenation (no filesystem needed).

Limitations

  • Text files only. Binary files (images, fonts, WASM, etc.) will be corrupted because std/utils reads all files as UTF-8 text via res.text(). Use external URLs, inline SVG, or icon fonts for images. This matches the current std/utils limitation.
  • precompressed is a no-op. Val Town doesn't store .br/.gz file variants, so the option is accepted but has no effect.
  • No filesystem directories. The isDir check uses a heuristic (no file extension = directory). Extensionless files like LICENSE or Makefile would be incorrectly treated as directories.
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
AboutAlternativesPricingBlogNewsletterCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.