Brett Codes

Building apps with Deno Fresh 2

I've been following along with the Fresh web app framework since I first learned about Deno a couple of years ago. Its promise is quite appealing: minimal config, Preact, use TypeScript without a compilation step, ship minimal JavaScript to the client.

In summer 2024 I built a web app powered by the first version of Fresh that was essentially a bespoke petition app. The development experience was quite nice. It was fast and easy to work with. But there was one bummer: hot module reloading (HMR) didn't work. Each change would result in a full page refresh, losing all state in the app. This is a bit of a deal breaker, especially when working on polished user interfaces.

In the time since that project, I did a lot of experimenting with using Deno with Vite and Preact without Fresh, basically building client-side single page apps for projects where that architecture makes sense. It was a positive experience, but not viable for all my needs. There are times when I'd prefer server-side rendering for more content-heavy pages and experiences. So I kept my eye on Fresh's development, hoping for improvements.

When Fresh 2 was announced in early September 2025 to be in Beta, I was super excited. The announcement came with HMR and faster boot times as the key features, which was enough to get me to jump back in and try it out.

I've built a few things so far with it:

I'm quite happy with the experience! There's been the occasional hiccup, like the dev server crashing due to temporary files (which I opened a PR to fix), but overall it feels quite stable.

I appreciate Deno's built-in commands like deno lint, deno fmt, deno check, and deno test all working without having to configure anything.

I've used it both with Tailwind and just vanilla CSS for styles. Preact is much like React and easy enough to pick up on if you're familiar with React. I've been writing tests using Deno's testing functionality at the integration and unit level, which has been straightforward and pleasant.

There's just something appealing to me about using Deno and Fresh contrasted to my day job where I'm using Node.js with TypeScript and Next.js with a bunch of other ancillary dependencies. Deno and Fresh are simple, which is really refreshing.

It's a bit surprising to me that at the time of this writing, Fresh 2 includes middleware plugins for CORS, CSRF, and CSP, but they aren't enabled by default (docs). This feels like an area where secure defaults would be valuable, even if you can opt out.

What I Like

What's Missing

Resources That'd Be Helpful

The topics that come to mind that would be great to have more resources on that most apps need:

I'm interested in possibly creating resources for Fresh relating to these topics.

Should You Use Fresh?

If you're starting a new project and want a refreshingly simple development experience, I think Fresh 2 is worth a try. It's especially well-suited for content-heavy sites, small-to-medium web apps, and side projects where you want to focus on building features rather than configuring tools.

The lack of HMR was a dealbreaker in Fresh 1, but with Fresh 2 addressing that pain point, it's become a genuinely viable framework to work with. I've found that Fresh does what it needs to and stays out of the way, letting me focus on what I'm building.

I'm looking forward to building more with it and seeing where the framework goes as it continues to mature.

August 2026 addendum: I continue to enjoy building web apps with Deno and Fresh. It's what I choose when I start building new web apps.

#deno #fresh #javascript #typescript #web