Up until now, anything your production/live website saved with Bun.write() would vanish the next time you ran git push. This is because each deploy rebuilds your site from scratch, nuking the previous deploy along with any files it had changed or created.
But there is a special folder that is treated differently. Anything you put in a data/ folder at the root of your repo will persist across deploys. When your website is deployed it mounts this persisted folder, which you can then use to keep files across git pushs.
data/ folder in gitWhile you develop your website locally, you'll probably want to read and write files in your data/ folder. But your live website won't see those files: it will mask the folder with a different folder that persists on the server across deploys. Because of this, it's important that you don't commit files from your local data/ folder to git.
Add this line to your .gitignore in the root of your repo:
data/
The data/ folder on the server is separate from anything you commit to git. If you don't .gitignore this folder and commit files into data/, the server's persistent data/ folder will sit on top and hide them, so your code would work locally but mysteriously can't find the files in production.
In your server.js, try something like this (by adding the two new routes below to your existing routes object in Bun.serve()):
let server = Bun.serve({
routes: {
'/save': async (req) => {
await Bun.write('data/notes.txt', await req.text())
return new Response('saved')
},
'/read': async () => {
let file = Bun.file('data/notes.txt')
if (!(await file.exists())) return new Response('nothing saved yet')
return new Response(file)
}
}
})
console.log(`Running on ${server.url}`)
Run it locally, POST something to /save (eg with curl -X POST -d 'hello' http://localhost:3000/save), then visit /read and you'll see the message you saved. You'll also see a file saved in your website's folder data/notes.txt, but if you git commit it won't commit that file. Your local site and live site on compsci.me will have different versions of that file, and importantly because it's in the data/ folder the live site's version will persist git pushs.
On your own laptop, data/ is just a normal folder sitting next to server.js and other files. But on the live website it actually lives elsewhere... though you still access it as though it lives next to server.js.
If your site needs a file to exist the very first time it runs, you can't just commit it as eg data/scores.json (see above - it'll be invisible in production). Instead, commit it under a different name and copy it on startup if it doesn't already exist:
// probably near the top of your server.js (outside of any route or Bun.serve)
if (!(await Bun.file('data/scores.json').exists())) {
await Bun.write('data/scores.json', Bun.file('scores.default.json'))
}
This way the file is there on first boot.
The whole server has limited disk space, shared between every student's site. Don't dump gigabytes of files into data/. If you need to store user-uploaded images or large media, talk to me first - you'll probably want S3 cloud files instead. I'm intending to set a soft limit of ~100MB per student, which should be more than enough for almost all use cases.
Your data persists across normal redeploys, but the server is a single machine and I don't currently back it up. If you're building something where losing the data would genuinely upset you (or your users), figure out a way to create your own backups or come and talk to me about how.