Shapeless helps you build fast, modern, fullstack apps with Next.js 15, Hono, and type-safe APIs—all optimized for Cloudflare Workers, Neon, and Drizzle ORM.
There are two ways to get started:
Using the CLI (recommended)
Manual setup (advanced)
If you used the CLI, everything is already set up. This guide walks through the core building blocks so you understand how your app works under the hood.
🗂️ Project Structure
Here’s the core file structure you'll see inside the resources/ directory of a Shapeless project:
create adds a new post with input validation via Zod
This file merges all routers and applies global middleware like CORS and error handling.
resources/index.ts
import { j } from "./shapeless"import { postRouter } from "./routers/post-router"const api = j .router() .basePath("/api") .use(j.defaults.cors) .onError(j.defaults.errorHandler)const appRouter = j.mergeRouters(api, { post: postRouter,})export type AppRouter = typeof appRouterexport default appRouter
All routes inside /api/post/* will now be handled by postRouter.
Shapeless encourages React Query for frontend API calls. Wrap your app with this provider:
resources/shared/providers.tsx
"use client"import { QueryCache, QueryClient, QueryClientProvider,} from "@tanstack/react-query"import { HTTPException } from "hono/http-exception"import { PropsWithChildren, useState } from "react"export const Providers = ({ children }: PropsWithChildren) => { const [queryClient] = useState( () => new QueryClient({ queryCache: new QueryCache({ onError: (err) => { if (err instanceof HTTPException) { // global error handling } }, }), }), ) return ( <QueryClientProvider client={queryClient}>{children}</QueryClientProvider> )}
5. Hook It Up in Next.js
To connect everything to your Next.js app, create a route handler at:
app/api/[[...route]]/route.ts
import appRouter from "@/resources"import { handle } from "hono/vercel"export const GET = handle(appRouter.handler)export const POST = handle(appRouter.handler)
For Cloudflare Workers, this setup is handled by OpenNext. Just build and deploy:
pnpm run cf:buildpnpm run cf:upload
✅ What’s Next
You're now ready to:
Build more routers
Define your Drizzle schema in db/schema.ts
Deploy to Cloudflare with one command
Make type-safe API calls using fetch() or React Query
Use this as your base, and expand however you want—admin studio, workflows, dashboard tools, auth systems—all built on this foundation.