tanstackReactHonoExample
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.
index.ts
https://neverstew--91fce8ac88574640b0f8895a510356b6.web.val.run
Full-stack message board built for Val Town.
- Hono web framework
- Drizzle ORM with SQLite
- Deno runtime
- React 19
- TanStack Router (code-first routing)
- TanStack Query (server state management)
- Tailwind CSS
- TypeScript
- Message board with persistent storage
- Client-side routing
- Optimistic updates
- Server-side data injection
- Type-safe database operations
βββ backend/ # Hono server running on Val Town
β βββ database/ # Drizzle schema, migrations, and queries
β βββ index.ts # Main Hono application
βββ frontend/ # React app running in browser
β βββ components/ # React components
β βββ lib/ # Utilities and hooks
β βββ router.tsx # TanStack Router configuration
βββ shared/ # Code shared between frontend and backend
GET /
- Serves the React application with initial dataGET /api/messages
- Fetch all messages (JSON)POST /api/messages
- Create a new messageGET /public/**
- Static assets (CSS, JS, etc.)/*
- All other routes handled by TanStack Router
- Read-only filesystem after deployment
- ESM imports via esm.sh for npm packages
- Code-first routing (no file-based routing)
const homeRoute = new Route({
getParentRoute: () => rootRoute,
path: "/",
component: () => <App {...window.__INITIAL_DATA__} />
});
export function usePostMessage() {
return useMutation({
mutationFn: (content: string) => postMessage(content),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["messages"] });
},
});
}
export const messages = sqliteTable("messages", {
id: integer("id").primaryKey({ autoIncrement: true }),
content: text("content").notNull(),
timestamp: text("timestamp").notNull().default(new Date().toISOString()),
});