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:
- Three different content-based websites
- A story authoring platform for writing and organizing creative fiction
- A URL shortener for managing links in my books and other projects
- A web app service for provisioning server instances
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
- Hot module reloading that actually works - The main reason I came back to Fresh 2, and it works as I'd expect. State persists between changes, making UI much faster now.
- Minimal configuration - Projects get up and running quickly without having to set up build tools and configs.
- Built-in tooling - Deno's baked-in linting, formatting, and testing tools mean fewer dependencies to manage.
- Fast deploys - Easy setup on Deno Deploy with incredibly fast deployment times.
- TypeScript without the hassle - No compilation step, no tsconfig, just write TypeScript and it all works.
What's Missing
- End-to-end testing tooling - While unit and integration testing work well with Deno's built-in test runner, I haven't explored how well tools like Playwright integrate yet. This is an area I'd like to learn more about.
- Ecosystem maturity - The Fresh ecosystem is still young compared to Next.js or other established frameworks. There are fewer ready-made solutions and examples to reference.
- Robust logging - Every web app needs logging, and I wish Fresh 2 came with a more robust logger that one could opt out of but was set up by default.
- Documentation - The docs are okay right now, but they're a bit thin on more advanced uses, like how to use Fresh 2 in a Deno Workspace.
Resources That'd Be Helpful
The topics that come to mind that would be great to have more resources on that most apps need:
- Database integration with Postgres
- Authentication (both traditional and OAuth)
- Reusable UI components
- Tailwind for styling
- Common utility helpers
- Security middleware (CORS, CSRF, CSP) enabled by default
- Structured logging
- Background job processing
- Email sending capabilities
- Comprehensive end-to-end tests
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.