diff --git a/examples/with-express/README.md b/examples/with-express/README.md
new file mode 100644
index 0000000..976c19b
--- /dev/null
+++ b/examples/with-express/README.md
@@ -0,0 +1,19 @@
+## Express example
+
+Shows how to use a hono app with express abd just using vite to build the entire app for development and production.
+
+## How to use
+
+Run the app in development mode
+
+> Builds the app, starts the express server and watches for changes
+
+```bash
+npm run watch
+```
+
+To start the express server
+
+```bash
+npm run start
+```
\ No newline at end of file
diff --git a/examples/with-express/package.json b/examples/with-express/package.json
new file mode 100644
index 0000000..bf7971b
--- /dev/null
+++ b/examples/with-express/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "with-express",
+ "version": "0.0.1",
+ "description": "",
+ "type": "module",
+ "private": true,
+ "scripts": {
+ "dev": "vite dev",
+ "build": "vite build",
+ "preview": "vite preview",
+ "start": "node ./dist/server.js",
+ "watch": "nodemon --watch './src/*' --exec 'pnpm run build && pnpm start' -e ts,js,svelte"
+ },
+ "keywords": [],
+ "dependencies": {
+ "express": "^4.19.2",
+ "hono": "^3.12.0",
+ "stack54": "^0.2.0",
+ "svelte": "^4.2.8"
+ },
+ "devDependencies": {
+ "@sveltejs/vite-plugin-svelte": "^3.0.1",
+ "@tsconfig/svelte": "^5.0.2",
+ "@types/express": "^4.17.21",
+ "nodemon": "^3.1.0",
+ "typescript": "^5.3.3",
+ "vite": "^5.0.10"
+ }
+}
diff --git a/examples/with-express/public/stack54.png b/examples/with-express/public/stack54.png
new file mode 100644
index 0000000..5154ed3
Binary files /dev/null and b/examples/with-express/public/stack54.png differ
diff --git a/examples/with-express/src/entry.ts b/examples/with-express/src/entry.ts
new file mode 100644
index 0000000..46a5507
--- /dev/null
+++ b/examples/with-express/src/entry.ts
@@ -0,0 +1,14 @@
+import { Hono } from "hono";
+import { view } from "stack54/view";
+
+import { render } from "./utils/view";
+
+const app = new Hono();
+
+app.use(view(render));
+
+app.get("/", async (ctx) => {
+ return ctx.render("welcome", {});
+});
+
+export default app;
diff --git a/examples/with-express/src/env.d.ts b/examples/with-express/src/env.d.ts
new file mode 100644
index 0000000..bd68f29
--- /dev/null
+++ b/examples/with-express/src/env.d.ts
@@ -0,0 +1,6 @@
+///
+///
+///
+
+///
+///
diff --git a/examples/with-express/src/server.ts b/examples/with-express/src/server.ts
new file mode 100644
index 0000000..c8dce68
--- /dev/null
+++ b/examples/with-express/src/server.ts
@@ -0,0 +1,25 @@
+import express from "express";
+import { toNodeHandler } from "stack54/node";
+import router from "./entry.js";
+
+const app = express();
+
+const serve_build = express.static("public/assets", {
+ immutable: true,
+ maxAge: "1y",
+});
+
+// http://expressjs.com/en/advanced/best-practice-security.html#at-a-minimum-disable-x-powered-by-header
+app.disable("x-powered-by");
+
+app.use("/assets", serve_build);
+
+app.use(express.static("public", { maxAge: "1h" }));
+
+app.all("*", toNodeHandler(router));
+
+const port = process.env.PORT || 3000;
+
+app.listen(port, () => {
+ console.log(`✅ app ready: http://localhost:${port}`);
+});
diff --git a/examples/with-express/src/utils/view.ts b/examples/with-express/src/utils/view.ts
new file mode 100644
index 0000000..62616ab
--- /dev/null
+++ b/examples/with-express/src/utils/view.ts
@@ -0,0 +1,11 @@
+import { makeFactory, resolveComponent } from "stack54/render";
+import { type TemplateModule } from "stack54/types";
+
+const components = import.meta.glob("../views/**/*.svelte", {
+ query: { ssr: true },
+ eager: true,
+});
+
+export const render = makeFactory((name) => {
+ return resolveComponent(`../views/${name}.svelte`, components);
+});
diff --git a/examples/with-express/src/views/components/document.svelte b/examples/with-express/src/views/components/document.svelte
new file mode 100644
index 0000000..74e9c73
--- /dev/null
+++ b/examples/with-express/src/views/components/document.svelte
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/with-express/src/views/welcome.css b/examples/with-express/src/views/welcome.css
new file mode 100644
index 0000000..17cbaa2
--- /dev/null
+++ b/examples/with-express/src/views/welcome.css
@@ -0,0 +1,9 @@
+html,
+body {
+ margin: 0;
+ color: white;
+ height: 100%;
+ line-height: 1.5;
+ background-color: black;
+ font-family: "Ubuntu", sans-serif;
+}
diff --git a/examples/with-express/src/views/welcome.svelte b/examples/with-express/src/views/welcome.svelte
new file mode 100644
index 0000000..c71129e
--- /dev/null
+++ b/examples/with-express/src/views/welcome.svelte
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/with-express/tsconfig.json b/examples/with-express/tsconfig.json
new file mode 100644
index 0000000..0c633f9
--- /dev/null
+++ b/examples/with-express/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "stack54/tsconfigs/base",
+ "include": ["src", "vite.config.ts"]
+}
diff --git a/examples/with-express/vite.config.ts b/examples/with-express/vite.config.ts
new file mode 100644
index 0000000..e90b962
--- /dev/null
+++ b/examples/with-express/vite.config.ts
@@ -0,0 +1,11 @@
+import { defineConfig } from "vite";
+import fullstack from "stack54/vite";
+
+export default defineConfig({
+ plugins: [fullstack()],
+ build: {
+ rollupOptions: {
+ input: {server: './src/server.ts'}
+ }
+ },
+});