Create a simple web app with Deno's Fresh
Tags: react, webdev, deno, javascript
Published: 2023-11-11 09:54:06

Hi everyone! In this post, I'll guide you through creating a simple website using the Fresh framework and explore its various features.

Fresh is a full-stack JavaScript framework built on Deno. It's easy to set up and comes with cool features like quick rendering, no build step, built-in Typescript support, and island architecture (partial hydration).

### What Am I Building?
I'm creating a straightforward speech-to-text web app using the Google Translate API. Check out the live demo app [here](https://text2audio.cc). You can find the complete code for this tutorial in my GitHub [repository](https://github.com/dunkbing/text2audio).

### Pre-requisites
- Deno 1.3x
- Familiarity with React and TypeScript

### Creating a New Fresh App
Run the following commands to generate a new Fresh application:

```bash
deno run -A -r https://fresh.deno.dev text2audio
cd text2audio
deno task start
```

Visit localhost:8080 to explore your new Fresh app.

![new-fresh-app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qnlrxe5smzak2uru6gzt.png)

The project you create will include three main folders:

1. **routes:** Handles routing, similar to frameworks like Next.js. Each file corresponds to a route or pattern, and each folder represents a sub-route. Routes can have handlers to manage the verb and define actions like rendering or returning a response.

2. **static:** Stores static assets resolved using "/" in HTML templates and CSS files. Caching can be managed using assets.

3. **islands:** Contains interactive islands in your project. Each file's name corresponds to the defined island. The code within this folder can run on both the client and server.

### Writing the Frontend and the API
Let's implement a Text Form and an API endpoint:

1) **Text Form:** Utilizes a POST form to submit to the `/audio` API to generate audio. Check out the code [here](#writing-the-frontend-and-the-api).

   ![text-form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jb6s1lwz2zvxtaf1z56c.png)

2) **API:** Creates an API endpoint `/api/audio` with a POST request to generate audio from text. View the code [here](#writing-the-frontend-and-the-api).

   Additionally, I use DenoKV to store the total generated audio, which looks like this:

   ```ts
   async function increaseTotalAudio(num: number) {
     try {
       const voicesEntry = await kv.get(voicesEntryKey);
       const currentTotal = voicesEntry.value;
       await kv.set(voicesEntryKey, currentTotal + num);
     } catch (error) {
       console.error("increaseTotalAudio error", error);
     }
   }
   ```

   For storing and serving audio files, I use Cloudflare R2, an S3-compatible storage service.

### Deployments
The site is deployed with Deno Deploy, linking your Git repository to a Deno project on Deploy.

![deno-deploy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9gnts9grnok0yo0x7b2.png)

Alternatively, you can use Docker with the provided Dockerfile.

### Performance
Fresh excels at boosting performance, as verified through PageSpeed Insights, generating a comprehensive report with all tested metrics.

![page-speed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9af8nvfyvnapyxxxeoe8.png)

### Conclusion
Fresh is an interesting framework, targeting monolithic applications, especially those combining frontend and backend with robust SSR. Despite some limitations, Fresh shows promise for a bright future. I hope you find this post helpful!