This is a starter kit for running a full-stack app quickly on Cloudflare without a complex framework. Pure JavaScript and standard technology to prevent lock-in.
Super lightweight, super fast, easy to understand, no magic (well, just a little). Uses flaregun for an awesome Cloudflare experience.
Out of the box, this includes:
- database with easy migrations
- file storage
- server side rendering
- API endpoints
- queues
- scheduler
- material 3 web components
- email and passkey authentication
It's easy to add and remove things since it's mostly just standard JavaScript.
You can get up and running in seconds (literally).
Want to deploy in seconds to see it in action?
Click Use this template button in the top right:
Then clone and run your new repo:
npm startNow view the demo page at http://localhost:8787.
Try making some changes and see it update in real-time!
Define models models in the data folder, then add the class to migrations.js to automatically keep your database schema up to date.
It's super easy to use the database:
let user = { name: 'John Wick', email: 'x@y.com' }
await c.data.d1.insert('users', user)
user.name = 'Jim Bean'
// update a row
await c.data.d1.update('users', user.id, user)
// get object
user = c.data.d1.get('users', user.id)
// querying
let users = await c.data.d1.query('users', {
where: { email: 'x@y.com' },
})See the D1 docs in the flaregun for more complex examples.
Edit layout.js to update the layout of your app.
This uses file based routing from Cloudflare Pages Functions, but runs on Workers because Pages Functions are deprecated.
To add a new route, just add a new file to the functions directory and that will be your route. For instance, if you add a file called hello.js, it will be available at
/hello.
For UI endpoints:
import { html } from 'rend'
export async function onRequestGet(c) {
return await c.data.rend.html({
main: render,
})
}
function render(d) {
return html` <div>Hello world!</div> `
}For API endpoints:
export async function onRequestGet(c) {
return Response.json({
hello: 'world',
})
}The scheduled.js file will run every minute by default (after your first deployment).
To disable scheduling, delete the scheduled.js file and remove the triggers from cloudflare.config.ts.
NOTE: There are some small gotchas here:
- This won't run any middleware, so you'll have to do any initialization you need in the scheduled function.
- To import something like a class or function in scheduled.js, it must also be used elsewhere in your app.
That's about it, otherwise, should work as is!
The queue.js file will run whenever you post a message to the queue.
To post a message:
await c.env.QUEUE.send({ message: 'Hello, world!' })Your queue.js handler will get the message shortly.
To delay the message:
await c.env.QUEUE.send({ message: 'Hello, world!' }, { delaySeconds: 60 })That will delay the message for 60 seconds.
This is configured to do some basic API testing with testkit. See tests/tests.js for more details. Run tests with npm run testkit and you can add that to your CI.
Just one command or setup auto deploy and you're live!
To deploy to production:
npm run deployTo create or update a preview for your current branch:
npm run previewPreviews give each branch an isolated, production-like environment with its own URL, variables, and preview-safe bindings configured for previews (ctx.isPreview) in cloudflare.config.ts.
Connect your Git repository in the Cloudflare Dashboard with Workers Builds:
- Production branch (
main): deploys automatically on push with production settings. - Other branches and pull requests: automatically build and deploy to isolated Worker Previews.
Set build command to:
npm run buildSet deploy command to:
npm run deploy