Fresh

Deno Fresh Review and Features

Written by Mojtaba Seyedi

Last update: 6/7/2024

Fresh is the newest addition to the growing list of meta frameworks, and it's built specifically for the Deno runtime. What sets Fresh apart from other frameworks is its unique approach to web development with its zero build step and minimalist design. This is particularly exciting news for developers, as they no longer have to spend time and resources on build configurations and can focus more on writing clean and maintainable code.

What is Fresh?

Fresh is an edge-native full-stack web framework for Deno with no build step. It has island architecture similar to Astro but uses Preact and JSX or TSX for rendering and templating. The framework embraces progressive enhancement through server-side rendering and ships zero javascript to the client by default. It is designed to optimize for latency and performance, making it an ideal choice for developers who want to deliver apps that can achieve high Lighthouse scores and function well in low-bandwidth areas.

Fresh has no build step

When you work with most JavaScript frameworks such as Next.js, Nuxt, Remix, and SvelteKit, you must first install your application's dependencies and then build the assets before deploying.

However, with Fresh, you don’t have a separate install step since all dependencies are installed and cached when it's run the first time. Also, Fresh doesn't have a build step, making it stand out from other frameworks.

With Fresh, when a request comes into the server, the framework renders each page on the fly and sends only HTML to the browser just-in-time, unless an island is involved, in which case only the required amount of JavaScript will be sent. This approach to the rendering process makes Fresh highly efficient and performant.

Moreover, Fresh's just-in-time builds eliminate the need for separate transpile steps. The Deno runtime transpiles TypeScript on request, allowing for server-side rendering and dynamic data passing through a template to generate HTML.

The fact that there's no bundling or transpiling involved makes it easy for developers to write browser-compatible JavaScript that uses web APIs like fetch and native ESM imports right from the start.

Thanks to its zero build step, deploying a Fresh app on Deno Deploy only takes seconds - simply upload a few kilobytes of JavaScript, and you're done.

Island based client hydration

Fresh is a server-side rendering framework that sends HTML to the client and does not ship any JavaScript by default. But what if you need an interactive component in your application that requires JavaScript? That's where partial hydration comes into play.

Fresh utilizes a modern architecture pattern known as "islands architecture" to enhance its performance and scalability. The islands architecture pattern allows for a cleaner separation of concerns and better performance by isolating Preact components that are rendered on the client.

In the case of Fresh, anything in the components folder is only used to create static HTML on the server and does not work in runtime. The only folder that contains JavaScript for runtime is the island folder. By using islands, Fresh ensures that only the JavaScript necessary for rendering the page is sent to the user, improving performance and reducing the amount of code that needs to be downloaded.

To create an island, simply create a file in the islands folder of your Fresh project, and give it a PascalCase or kebab-case name. For instance, a file named MyIsland.tsx can contain the following code:

import { useState } from "preact/hooks";

export default function MyIsland() {
  const [count, setCount] = useState(0);

  return (
    <div>
      Counter is at {count}.{" "}
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}

You can use an island in a Fresh page just like any other Preact component, and Fresh will take care of automatically re-hydrating the island on the client. By enabling client-side interactivity, islands enhance the user experience and make Fresh an even more powerful framework for building modern web applications.

Fresh is an edge native framework

Fresh is a web framework designed to take advantage of the edge environment. The edge combines the benefits of CDNs and serverless computing, allowing custom code to be executed close to users. With Fresh, developers can render pages and execute custom code right at the edge, providing users with a lightning-fast experience.

While edge development can be complex due to the hybrid nature of rendering choices, Fresh simplifies the process by embracing server-side rendering and an islands architecture.

Furthermore, being edge-native means that Fresh can leverage the power of Deno Deploy, making it easy to deploy globally and manage infrastructure without worrying about scaling. By using Fresh with Deno Deploy's globally distributed JavaScript serverless edge network, developers can achieve benefits such as latency optimization and a perfect Lighthouse score.

File Structure

A basic project structure in Fresh is as follows:

my-fresh-project/
├── deno.json
├── dev.ts
├── main.ts
├── fresh.gen.ts
├── import_map.json
├── islands
│   └── Counter.tsx
├── routes
│   ├── [name].tsx
│   ├── api
│   │   └── joke.ts
│   └── index.tsx
└── static
    ├── favicon.ico
    └── logo.svg
  • dev.ts: This is the dev server. It is the development entry point for the project.
  • main.ts: This is the production entry point for your project. It is the file that you link to Deno Deploy.
  • fresh.gen.ts: This file is automatically generated and contains information about your routes and islands.
  • import_map.json: This file shows where to get the dependencies for the project. It makes importing and updating dependencies easier.
  • deno.json: This is kind of like package.json, except there are no dependencies. It shows the location of the import_map.json so that it can be loaded automatically. Also, there are some task commands like npm scripts in package.json here.
  • routes: This folder is where you define all your routes. The names of each file in this folder correspond to the path where that page will be accessed. Note that the code inside this folder is never directly shipped to the client.
  • islands: This folder is where you define all of the interactive islands in the project. The name of each file corresponds to the name of the island defined in that file. The code inside this folder can be run from the client and server.
  • static: This folder contains public static assets served automatically as they are, like images, fonts, etc.

Ecosystem

As a relatively new web framework, Fresh is still building its ecosystem. However, there are already some resources available for developers to utilize. The Fresh website has a components page where developers can find pre-built UI components that they can use to prototype their applications quickly.

Additionally, the Deno Discord community is a great place to ask questions, get help, and connect with other developers who are using Fresh. There, you can find dedicated channels for Fresh-specific discussions and support.

Finally, the Fresh repository on GitHub is a good place to report bugs, request features, or start a discussion about the framework. The discussions section of the repository allows developers to engage in open discussions about the development of Fresh.

Although Fresh is new, with the backing of the Deno community and the momentum behind the project, the Fresh ecosystem will likely continue to grow and evolve in the coming years.

Showcase

[@portabletext/react] Unknown block type "showcase", specify a component for it in the `components.types` prop

How to get started With Fresh?

Before creating your first project using the Fresh framework, you need to have Deno 1.25.0 or later installed. You can follow the installation instructions on Deno’s documentation.

Also, it’s good to have the Deno extension installed on your IDE, if this is your first experience with Deno.

Run the following command to bootstrap a new project with Fresh:

deno run -A -r https://fresh.deno.dev my-project

Switch into the new directory:

cd my-project

Start the development server:

deno task start

Open http://localhost:8000 in your browser to see your project live.

Deploying Fresh to the edge

Fresh is designed to be deployed and hosted on the edge using Deno Deploy, but it can also be deployed on any platform or system that supports a Deno-based web server or Docker containers, such as Amazon Web Services or Google Cloud.

Deno Deploy is a globally distributed edge runtime built by the Deno company. It is excellent for hosting serverless functions as well as entire websites and applications. Here is how you can deploy your project to Deno Deploy in a few simple steps:

  • Create a GitHub repo for your project
  • Go to dash.deno and connect your GitHub
  • Select your GitHub organization or user, repository, and branch
  • Select “Automatic” deployment mode and main.ts as an entry point
  • Click “Link”, which will start the deployment

When the deployment is complete, you’ll receive a URL that you can visit to see the live version of your application.

Check out the Fresh documentation for more specific guides on how to deploy to various platforms.

Final Thoughts

Fresh is a promising web framework that aims to simplify the process of building web applications with Deno. Its minimalist approach to web development allows developers to focus on writing clean, concise, and maintainable code. With its focus on ease of use, developer productivity, and fast performance, Fresh offers a simple and intuitive development experience for Deno developers.

[@portabletext/react] Unknown block type "prosCons", specify a component for it in the `components.types` prop