title: | 'touch a_website.http.tsx' with VT, Val Town's CLI
|
---|---|
description: | Making VT, the official command line tool to edit, manage, and begin Val Town projects from your terminal |
pubDate: | 2025-04-17T00:00:00.000Z |
author: | Wolf Mermelstein |
I love tools. I also love simplicity and versatility. What I don't love is friction. Since learning to code, Over the years, I've ended up writing a lot of random, often, one-off tools, scripts, and programs for myself, often to solve hyper-specific problems that make my life easier, or sometimes just for fun. But all of these tools and scripts have always been local programs, often in Python or Typescript, and generally packaged for my own use. I usually don't bother to write my tools with consideration for any platform other than my own, because, well, there's too many.
But these have always been local scripts or programs, because creating versatile, web-based tools is just too much work, and it's never simple.
Earlier this year, I found the answer to the quandary with Val Town. Val Town removes the friction in creating and shipping web apps. Now, I could write all the stuff I already was going to, often already in Typescript, but ship it to a platform accessible to everyone. So, since starting using Val Town I've created a new net of, random scripts, but this time they're websites!
But, while I'm a big tooling geek, and love web technologies, I'm also drawn to my Linuxy, Neovim+tmux, CLI ways. So, naturally, when I started using Val Town I immediately craved a local dev experience more robust than my initial copy+paste flow.
I decided to tackle this by implementing a FUSE file system for Val Town, ValFS. The initial concept was very simple--you'd directly edit off Val Town, but locally, similar to how one might edit Google Docs files with RClone. FUSE is a Linux protocol that lets you handle file system syscalls, like writing or reading chunks of files, in a userspace program. I built ValFS in go with go-fuse, and it would expose a folder with all your Vals in it. If you wrote to a Val, it would automatically upload the new modifications to Val Town. There were no state issues, since if it failed to upload, the write itself would be rejected.
I had a lot of fun plans for ValFS -- letting users modify metadata and access all parts of the Val Town API through a file interface (much like UNIX file descriptors!), and making the "Val" files executable, so you could run them on the Val Town platform and get the output through stdout, like ./myVal.HTTP.tsx
. ValFS worked quite well, and proved the concept.
Val Town's CLI, vt
, leverages Val Town to let you instantly ship Typescript files on your computer to a deployed, scalable, HTTPS website (or API). No configuring, no bundling, no certs. Just code --> prod!
With vt
, you can:
- Watch a folder for changes, deploying changes to prod in less than a second of saving
- Manage branches, to easily switch between separate deployments, like a prod and test branch, or just to keep yourself organized
- Remix or create brand-new Val Town projects directly from your command line
vt
is built entirely in Typescript w/ native Deno, a modern JavaScript runtime, so vt
is cross-platform. If you already have Deno you can run vt
now with vt run -A jsr:@valtown/vt
to quickly get started. If you don't, check out Deno's install instructions here.
vt
works much like git
; Val Town projects act somewhat like repos, so most commands should come naturally. vt
can resolve complex deltas between Val Town and a local folder of Typescript and text files, automatically detecting file changes like renames and modifications. You can work locally, and, when you're ready, ship with vt push
.
It's also fast! Operations happen concurrently where possible. Watch 62 files get cloned in 0.17 seconds!
vt
lets you create new projects. You can remix a very minimal HTTP, Hono, React, template, with vt remix @std/reactHonoTemplate myNewVal
, and then cd
into the new folder with cd myNewVal
. Or, you can create a blank project from scratch with vt create
.
Then run vt browse
so you can view your new, deployed, website!
Then, just run vt watch
so that vt
automatically does a vt push
whenever changes are detected in the folder.
vt
unlocks many new workflows previously not possible on Val Town. Recently, we saw Geoffrey Litt's Stevens project, a really cool AI personal assistant telegram bot, built locally with cursor and vt
. I've been working on a project using Neon Postgres, and doing migrations locally with DrizzleKit, using vt
to sync schemas. Being able to use your local dev tools, whether AI ones like Cursor and Claude Code, or a highly customized Neovim and CLI tools like ripgrep, and the full Deno language server is very powerful!
vt
takes a lot of inspiration from similar Val Town local dev projects, like @pomdtr's Val Town VSCode extension and WebDav server, and my previous local Fuse filesystem implementation for Val Town, valfs. We'd also like to thank our beta testers, who helped influence the file naming algorithm, choosing default editor files, helping us find bugs, and more.
We're excited to keep improving vt
! We have a lot planned: automatic reloading during vt watch
with a zero-config companion browser extension, a Typescript library exposing vt
's internal functionality (like pushing & pulling delta resolution), commands to manage PRs, and more! We love getting to user feedback and seeing what you build! Please join our discord server to share any and all feedback, and how VT has shaped your workflows.
vt
is open source, and the Github can be found at https://github.com/val-town/vt, and the JSR page here!