AdelieStack Svelte Themes

Adeliestack

A SvelteKit + Hono + Drizzle template

Sveltekit - Adelie Stack

This stack is a cloned and modified version of GitHub user Rykuno's TofeStack.

ā” What

A scalable, testable, extensible, template for Sveltekit.

Sveltekit is awesome, but sometimes you need a bit more capability in the backend than what frameworks like NextJS & Sveltekit can deliver.

To remedy this, I've attached a fully fleshed out backend to run on the Sveltekit process and forward all API requests to it and paired it with some architectural patterns.

/api/[...slugs]

import app from '$lib/api';
import type { RequestHandler } from '@sveltejs/kit';

export const GET: RequestHandler = ({ request }) => app.fetch(request);
export const PUT: RequestHandler = ({ request }) => app.fetch(request);
export const DELETE: RequestHandler = ({ request }) => app.fetch(request);
export const POST: RequestHandler = ({ request }) => app.fetch(request);
export const fallback: RequestHandler = ({ request }) => app.fetch(request);

Local Setup

  1. Make sure Docker is running
  2. Copy the .env.example file and rename to .env
  3. Ensure that DB_SEEDING and DB_MIGRATING are set to true in the .env for this first run.
  4. pnpm install
  5. The database extension citext is being used to allow for case-insensitive string matching. To install the extension run CREATE EXTENSION IF NOT EXISTS citext; or add inside an additional drizzle SQL file for startup to use.
  6. pnpm initialize (this will start the docker-compose and run the initial database migration.)
  7. pnpm dev
  8. Ensure that DB_SEEDING and DB_MIGRATING are set back to false in the .env after initial set up.

No additional setup is required, zero api keys, zero services to signup for, zero cost.

How to Use

This is not supposed to serve as an all batteries included "production boilerplate" with 200 useless sponsored features that get in your way. Templates that do this are ANYTHING but "production" and "quick start".

This is stack is designed to be library agnostic. The philosophy here is to boostrap the concrete, repetitive, and time-consuming tasks that every application will need regardless of what you're building.

So - fork this repo, add your favorite libraries, and build out your own "more opinionated" personal template tailored to you!

Features

  • šŸŸ¢ Full E2E typesafety
  • šŸŸ¢ RPC Client for API Requests
  • šŸŸ¢ Custom Fetch Wrapper
  • šŸŸ¢ Deployment Template
  • šŸŸ  Authentication
    • šŸŸ¢ Email / Passkey
    • šŸŸ¢ Username / Email and Password
    • šŸ”“ OAuth
    • šŸŸ¢ Email Update / Verification
    • šŸŸ¢ Rate limiter

Technologies

I'm mostly un-opinionated of what technology or libraries someone uses. Wanna uwu'ify your entire app? Go for it.

That being said, there are some libraries that embody my philosophies of building software more than others,

  • Oslo-project: Used for implementing crypto, encoding, hashing, and more in the authentication layer.
  • ArcticJS: Arctic is a collection of OAuth 2.0 clients for popular providers. It only supports the authorization code grant type and intended to be used server-side.
  • Drizzle - Drizzle advertises itself as an ORM, but I think its deceptive. It's a query builder with a migration client. Everytime I've used an ORM, I find myself fighting it for sometimes the simplest of use cases. Drizzle just gives you type-safety while querying SQL in a native fashion. Learn SQL, not ORMs.
  • Hono: Fast, lightweight, and built on web standards; meaning it can run anywhere you're SvelteKit app can. It's essentially a better, newer, and ironically more stable Express.JS. This provides us a perfect foundation to cleanly build on top of without having to teardown first. It has a zod adapter for validating DTO's which can be shared with the frontend too.
  • SvelteKit: After trying Vue, React, Next, and pretty much every frontend framework in the JS ecosystem, it's safe to say I vastly prefer Svelte and its priority of building on web standards.

Architecture

There are a few popular architectures for structuring backends. Technical, Onion, DDD, VSA, and the list goes on. I almost always choose to start with Technical and let the project naturally evolve into one of the others as complexity grows.

Backend Folder Structure

  • controllers - Responsible for routing requests

  • services - Responsible for handling business logic.

  • repositories - Responsible for retrieving and storing data.

  • infrastructure - Handles the implementation of external services or backend operations.

  • middleware - Middlware our request router is responsible for handling.

  • providers - Injectable services

  • dtos - Data Transfer Objects (DTOs) are used to define the shape of data that is passed.

  • common - Anything commonly shared throughout the backend

File Naming

You might notice how each file in the backend is postfixed with its architectural type(e.g. iam.service.ts). This allows us to easily reorganize the folder structure to suite a different architecture pattern if the domain becomes more complex.

For example, if you want to group folders by domain(DDD), you simply drag and drop all related files to that folder.

ā””ā”€ā”€ events/
    ā”œā”€ā”€ events.controller.ts
    ā”œā”€ā”€ events.service.ts
    ā””ā”€ā”€ events.repository.ts

Testing

Testing probably isn't first and foremost when creating an app. That's fine. You should not be spending time writing tests if your app is mutable.

BUT, a good stack should be testable when the time to solidify a codebase arrives. I created this stack with that principle in mind. I've provided a examples of how to write these tests under authentication.service.test.ts or users.service.test.ts

Top categories

Loading Svelte Themes