cd..blog

Seamless Frontend Deployment: Preact, Docker, Heroku with TypeScript

const published = "Dec 23, 2025, 10:21 PM";const readTime = 5 min;
preactdockerherokutypescriptfrontend
Discover how to integrate Preact, Docker, and Heroku using TypeScript for a robust, scalable frontend deployment. Learn containerization, multi-stage builds, and Heroku's Container Registry.

Seamless Frontend Deployment: Preact, Docker, and Heroku with TypeScript

Modern web development thrives on efficiency and scalability. Integrating a lightweight frontend like Preact with robust containerization via Docker and streamlined deployment on Heroku offers a powerful stack. This guide demonstrates how to combine these technologies, all powered by TypeScript, for a production-ready application.

1. Setting Up the Preact Frontend with TypeScript

We'll start by scaffolding a Preact project using Vite, a fast build tool that provides excellent TypeScript support out-of-the-box. Preact offers a performant, 3KB alternative to React, ideal for lightweight applications.

// Install Vite and create a new project
npm create vite@latest my-preact-app -- --template preact-ts
cd my-preact-app

// Basic Preact component in src/app.tsx
import { useState } from 'preact/hooks';
import preactLogo from './assets/preact.svg';
import viteLogo from '/vite.svg';
import './app.css';

export function App() {
  const [count, setCount] = useState<number>(0);

  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} class="logo" alt="Vite logo" />
        </a>
        <a href="https://preactjs.com" target="_blank">
          <img src={preactLogo} class="logo preact" alt="Preact logo" />
        </a>
      </div>
      <h1>Vite + Preact</h1>
      <div class="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <p>
          Edit <code>src/app.tsx</code> and save to test HMR
        </p>
      </div>
      <p class="read-the-docs">
        Click on the Vite and Preact logos to learn more
      </p>
    </>
  );
}

This sets up a basic Preact application that will be built into static assets.

2. Containerizing with Docker for Production

Containerization with Docker ensures your application runs consistently across environments. We'll use a multi-stage Dockerfile to optimize image size and securely serve the Preact build output using Nginx. This approach separates build dependencies from the runtime environment.

Create a Dockerfile in your project root:

# Stage 1: Build the Preact application
FROM node:20-alpine AS build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Stage 2: Serve the application with Nginx
FROM nginx:stable-alpine AS production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
# Optional: Custom Nginx configuration (e.g., for routing)
# COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

This Dockerfile first builds the Preact application and then copies the resulting static files into an Nginx server, ready for deployment. The nginx:stable-alpine image is chosen for its small footprint.

3. Deploying to Heroku with Container Registry

Heroku's Container Registry provides a seamless way to deploy Dockerized applications. Instead of managing Docker Hub directly, Heroku can build and host your images. We'll use heroku.yml to define the build and release process, making deployments declarative and repeatable. Heroku automates the process of building the Docker image from your Dockerfile and deploying it.

Create a heroku.yml file in your project root:

build:
  docker:
    web: Dockerfile
release:
  # Commands to run after a successful build, before the app is deployed
  # For a static frontend, this might be empty or include cache invalidation
  # command: 
run:
  web: nginx -g "daemon off;"

To deploy, ensure you have the Heroku CLI installed and logged in:

heroku login
heroku create my-preact-app-ts # Replace with a unique app name
git push heroku main

Heroku will detect the heroku.yml file, build your Docker image using the specified Dockerfile, and then release it. Your Preact application will be served by Nginx within the Heroku dyno.

Conclusion

By integrating Preact, Docker, and Heroku with TypeScript, you establish a robust and efficient development and deployment pipeline. This setup leverages Preact's performance, Docker's consistency, and Heroku's ease of deployment, allowing developers to focus on building features rather than infrastructure. This architecture is highly scalable for single-page applications and provides a clear path for future enhancements.