Skip to main content

Thinkserver: my web-based coding environment

I've made my own web-based coding environment for working on little projects.

A few years ago I found Glitch.

It's great: a web-based coding environment that makes it really easy to quickly start editing a web page. It has a live preview that helps to quickly see changes take effect.

But over time, as more and more of my stuff ended up living on Glitch, I was a bit uneasy about relying on someone else's service, and I also wanted to make some changes that would be idiosyncratic. In particular, I make a lot of things with Elm and while Glitch has some mechanisms for changing how a project is built, it's not documented well and my solution kept breaking. I also keep having trouble logging into Glitch, and the editor doesn't work particularly well on my phone.

So I decided to try making my own knock-off.

I've been using it for about a year now. I'm really happy with it and I feel like I should share it, in case it's useful to anyone else.

The back-end is a Django server which keeps some metadata about projects: just a name and the creation time, really. Each project has a directory on disk where all its files are kept.

Glitch gives new projects a name randomly-generated from a list of nice words. It troubles me that they're not namespaced by user, but I can also avoid thinking about that because I'm the only user of my server. For my list of nice words, I decided to write down a food starting with each letter of the alphabet, and use three of them for a project name. That gives me 17576 possible projects, which I think is plenty.

The public view of each project is served from a subdomain <project>.think.somethingorotherwhatever.com. I got a wildcard certificate from Let's Encrypt.

I added a flag to set a project as a "template", which I can remix from the server's home page. This is really handy as a way of starting off a project. I have a generic "page" template, one for Elm which has all the necessary JSON files and a Makefile to build it, as well as a couple more templates to do with libraries I often look at for work.

The index page. A list of templates, a list of recent projects, then collapsed categories.

The index page. I've got list of templates and recent projects for quick access, then everything else is organised into categories.

The editor interface is an Elm page showing an editor interface, the file tree, the build log and a live preview.

As I type in the editor, the file is automatically saved. If there's a Makefile in the project's root directory, it's run each time a file is saved. I can configure which file extensions will trigger a make with the file .watchmakerc.

The editor interface. The title, "metro-info", at the top, and some links to preview, rename, delete or remix it. Then a three-column interface with a file tree and logs, a code editor, and a live preview.

The editor interface.

After a while, I added a little form to run a shell command in the project's directory, to do things like install Elm packages or copy files from other projects. Because I'm the only user, I can be quite relaxed about the security implications of this.

And then I added a form just for installing Elm packages, so I can just type elm/json instead of bash -c "echo 'Y' | elm install elm/json".

That's pretty much it! It's satisfying how little work I needed to do to make a coding environment that I really enjoy.

As I write this I've got 80 projects in my think server. A lot of them are little things I made as quick experiments or pieces of art. A handful of them are tools that I use every day, like my Metro arrival times page.

This weekend, I got antsy about how many things I have in this server with no backup, so I spent some time adding tools to commit to a Git repository and push it to my home Forgejo instance.

I spent a few hours making a very complicated system for doing git commits through the web interface before I remembered that Jujutsu (jj) exists, and switched to that. The way jj works suits this case much better than git: you don't explicitly add particular files to the repository or have a staging environment. Instead, the current state of the working directory is supposed to be the same as the state of the top of the repository, and you have to explicitly ignore files that you don't want to check in. So I just need a "commit" command in the editor which takes a message and adds a commit to the repo history, without any other decisions to make.

I discovered the "create-on-push" feature of Forgejo, so I can also push the repository without having to go to Forgejo to create a corresponding repo there.

The thinkserver code is on my Forgejo instance. Feel free to take it, run it yourself and modify it.

I'm not interested in making this a collaborative project, or taking feature requests. Please don't make me regret sharing it by finding security vulnerabilities!