TheOnlyWayUp / create-t3svelte-app

Quick T3 Stack with SvelteKit for rapid deployment of highly performant typesafe web apps.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

T3-SvelteKit

create-t3svelte-app

NPM version License Stars Downloads


Just Build
npx create-t3-app

Get Building

✅ Elegant full-stack framework powered by SvelteKit.
✅ Static typing support with TypeScript
✅ End-to-end typesafe APIs with tRPC.io
✅ Enjoyable database interaction with Prisma ORM.
✅ Efficient styling with Tailwind CSS.

NPM & Yarn

npx create-t3svelte-app@latest

Early Version Note

This initial version is lacking significant polish that I hope to add in a new release shortly, including:

  • Less Opinions, More Customization (including prettier/eslint not as forced defaults)
  • SQLite as Prisma.schema default ✅
  • Helper comments
  • Package Manager Support

More Info 🛠

Basics

A simple CLI with highly opioniated out-of-the-box ready SvelteKit/tRPC/Prisma/Tailwind application with CLI options: 'Standard' and 'Standard + UI Extras' (customization soon). Just run and start building.

Standard

  • SvelteKit
  • tRPC - preconfigured with example API call in +page.svelte
  • Tailwind CSS - preconfigured with eslint/prettier & 'tailwind prettier plugin' integration
  • Prisma ORM - CLI option to initialize DB on run - no need to run prisma db pull or prisma db generate

Standard + UI Extras

  • Standard
  • Headless UI
  • HeroIcons

Prisma Reqs

If you choose not to init DB on first build, you can initialize prisma db at any time by editing the DATABASE_URL in .env and then running npx prisma db pull and npx prisma generate. You can read more about Prisma on their docs Here

Shoutouts

Theo @ T3 for T3 Stack inspiration!
Nexxel for the OG create-t3-app!
Ionut-Cristian Florescu for his wonderful work on SvelteKit + tRPC & SSR Info!
Ryan Gossiaux for enabling TailwindUI & HeadlessUI on Svelte!

Caveats & Addendums

Server-Side Rendering

If you need to use the tRPC client in SvelteKit's load() function for SSR, make sure to initialize it like so:

// $lib/trpcClient.ts
import { browser } from '$app/env';
import type { Router } from '$lib/trpcServer';
import * as trpc from '@trpc/client';
import type { LoadEvent } from "@sveltejs/kit";

const url = browser ? '/trpc' : 'http://localhost:3000/trpc';
export default (loadFetch?: LoadEvent['fetch']) =>
  trpc.createTRPCClient<Router>({
    url: loadFetch ? '/trpc' : url,
    transformer: trpcTransformer,
    ...(loadFetch && { fetch: loadFetch as typeof fetch })
  });
  

Then use it like so:

// index.svelte
import trpcClient from '$lib/trpcClient';
import type { Load } from '@sveltejs/kit';

export const load: Load = async ({ fetch }) => { // 👈 make sure to pass in this fetch, not the global fetch
	const authors = await trpcClient(fetch).query('authors:browse', {
		genre: 'fantasy',
	});
	return { props: { authors } };
};

Vercel's Edge Cache for Serverless Functions

Your server responses must satisfy some criteria in order for them to be cached Verced Edge Network, and here's where tRPC's responseMeta() comes in handy. You could initialize your handle in src/hooks.ts like so:

// src/hooks.ts or src/hooks/index.ts
import { router } from '$lib/trpcServer';
import { createTRPCHandle } from 'trpc-sveltekit';

export const handle = async ({ event, resolve }) => {
  const response = await createTRPCHandle({
    url: '/trpc',
    event,
    resolve,
    responseMeta({ type, errors }) {
      if (type === 'query' && errors.length === 0) {
        const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
        return {
          headers: {
            'cache-control': `s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS}`
          }
        };
      }
      return {};
    }
  });

  return response;
};

License

MIT

About

Quick T3 Stack with SvelteKit for rapid deployment of highly performant typesafe web apps.

License:MIT License


Languages

Language:JavaScript 57.4%Language:TypeScript 31.2%Language:Svelte 7.5%Language:HTML 3.3%Language:CSS 0.7%