├── .github
└── workflows
│ └── publish.yaml
├── .gitignore
├── LICENSE
├── README.md
├── bin
└── create-t3svelte-app.js
├── overwrites
├── mongodb
│ └── prisma
│ │ └── schema.prisma
├── mysql
│ └── prisma
│ │ └── schema.prisma
└── postgres
│ └── prisma
│ └── schema.prisma
├── package.json
├── src
├── cli.js
└── main.js
└── templates
├── +eslint_javascript
├── .eslintignore
├── .eslintrc.cjs
└── package.txt
├── +eslint_prettier_javascript
├── .eslintignore
├── .eslintrc.cjs
├── .prettierignore
├── .prettierrc
└── package.txt
├── +eslint_prettier_typescript
├── .eslintignore
├── .eslintrc.cjs
├── .prettierignore
├── .prettierrc
└── package.txt
├── +eslint_typescript
├── .eslintignore
├── .eslintrc.cjs
└── package.txt
├── +headlessui
└── package.txt
├── +heroicons
└── package.txt
├── +prettier
├── .prettierignore
├── .prettierrc
└── package.txt
├── +prisma
├── package.txt
├── prisma
│ └── schema.prisma
└── src
│ └── lib
│ └── server
│ └── prismaClient.ts
├── +prisma_trpc
├── package.txt
├── prisma
│ └── schema.prisma
└── src
│ ├── hooks.server.ts
│ └── lib
│ ├── client
│ └── trpc.ts
│ └── server
│ ├── prismaClient.ts
│ └── trpcServer.ts
├── +tailwind
├── package.txt
├── postcss.config.cjs
├── src
│ ├── app.css
│ └── routes
│ │ └── +layout.svelte
├── svelte.config.js
└── tailwind.config.cjs
├── +tailwind_prettier_plugin
└── package.txt
├── +trpc
├── package.txt
└── src
│ ├── hooks.server.ts
│ └── lib
│ ├── client
│ └── trpc.ts
│ └── server
│ └── trpcServer.ts
├── base_javascript
├── .gitignore
├── .npmrc
├── README.md
├── jsconfig.json
├── package.json
├── src
│ ├── app.d.ts
│ ├── app.html
│ └── routes
│ │ └── +page.svelte
├── static
│ └── favicon.png
├── svelte.config.js
└── vite.config.js
├── base_typescript
├── .gitignore
├── .npmrc
├── README.md
├── package.json
├── src
│ ├── app.d.ts
│ ├── app.html
│ └── routes
│ │ └── +page.svelte
├── static
│ └── favicon.png
├── svelte.config.js
├── tsconfig.json
└── vite.config.ts
└── standard
├── .eslintignore
├── .eslintrc.cjs
├── .gitignore
├── .npmrc
├── .prettierignore
├── .prettierrc
├── README.md
├── package.json
├── postcss.config.cjs
├── prisma
└── schema.prisma
├── src
├── app.css
├── app.d.ts
├── app.html
├── hooks.server.ts
├── lib
│ ├── client
│ │ └── trpc.ts
│ └── server
│ │ ├── prismaClient.ts
│ │ └── trpcServer.ts
└── routes
│ ├── +layout.svelte
│ └── +page.svelte
├── static
└── favicon.png
├── svelte.config.js
├── tailwind.config.cjs
├── tsconfig.json
└── vite.config.ts
/.github/workflows/publish.yaml:
--------------------------------------------------------------------------------
1 | name: "🚀 publish"
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | release:
10 | name: 🚀 publish
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: 📚 checkout
14 | uses: actions/checkout@v3
15 | - name: 🟢 node
16 | uses: actions/setup-node@v3
17 | with:
18 | node-version: 18
19 | registry-url: https://registry.npmjs.org
20 | - name: 🚀 publish
21 | run: npm publish --access public
22 | env:
23 | NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 zach-hopkins
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
*Looking for Maintainers! Message me...*
4 |
5 |
6 | create-t3svelte-app
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Just Build
27 |
28 | npx create-t3svelte-app
29 |
30 |
31 |
32 | ## Outline
33 |
34 | * [Get Building](#get-building)
35 | * [npm](#npm)
36 | * [yarn](#yarn)
37 | * [Prisma Requirements](#prisma-requirements)
38 | * [Available Templates](#available-templates)
39 | * [Standard](#standard-recommended)
40 | * [Custom (Modular)](#custom-modular-build)
41 | * [Contributing](#contributing)
42 | * [Caveats & Addendums](#caveats--addendums)
43 | * [Server-Side Rendering](#server-side-rendering)
44 | * [Vercel's Edge Cache for Serverless Functions](#vercels-edge-cache-for-serverless-functions)
45 | * [Shoutouts](#shoutouts)
46 | * [License](#license)
47 |
48 | ## Get Building
49 | create-t3svelte-app is completely modular. Choose the components you need!
50 |
51 | ✅ Elegant full-stack framework powered by [SvelteKit](https://kit.svelte.dev/)
52 | ✅ Static typing support with [TypeScript](https://typescriptlang.org)
53 | ✅ End-to-end typesafe APIs with [tRPC](https://trpc.io)
54 | ✅ Enjoyable database interaction with [Prisma](https://www.prisma.io/)
55 | ✅ Efficient styling with [Tailwind CSS](https://tailwindcss.com/)
56 |
57 | ### npm
58 |
59 | ```bash
60 | npx create-t3svelte-app@latest
61 | ```
62 |
63 | ### yarn
64 |
65 | ```bash
66 | yarn create t3svelte-app
67 | ```
68 |
69 | ### Prisma Requirements
70 |
71 | 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](https://www.prisma.io/docs/reference/api-reference/command-reference).
72 |
73 | ## Available Templates
74 |
75 | A simple CLI with highly opinionated, out-of-the-box ready SvelteKit/tRPC/Prisma/Tailwind application. CLI options include 'Standard' and 'Custom' (modular build). Just run and start building.
76 |
77 | ### Standard (Recommended)
78 |
79 | - [**SvelteKit**](https://kit.svelte.dev/)
80 | - [**TypeScript**](https://www.typescriptlang.org/)
81 | - [**tRPC**](https://trpc.io/) - preconfigured with example API call in `+page.svelte`
82 | - [**Tailwind CSS**](https://tailwindcss.com/) - preconfigured with eslint/prettier & 'tailwind prettier plugin' integration
83 | - [**Prisma ORM**](https://www.prisma.io/) - CLI option to initialize DB on run - no need to run `prisma db pull` or `prisma db generate`
84 |
85 | ### Custom (Modular Build)
86 |
87 | #### Tech Stack Options:
88 |
89 | - SvelteKit
90 | - TypeScript || JavaScript
91 | - tRPC
92 | - Tailwind CSS
93 | - Prisma ORM
94 |
95 | #### Tool Options:
96 |
97 | - [ESLint](https://eslint.org/)
98 | - [Prettier](https://prettier.io/)
99 | - [Tailwind Prettier Plugin](https://github.com/tailwindlabs/prettier-plugin-tailwindcss)
100 | - [Prisma ORM](https://www.prisma.io/)
101 | - [Svelte Headless UI](https://github.com/rgossiaux/svelte-headlessui)
102 | - [Svelte HeroIcons](https://github.com/JustinVoitel/svelte-hero-icons)
103 |
104 | #### Config Options:
105 |
106 | - Git Init
107 | - DB Auto Configure w/ Prisma (Postgresql, MySQL, MongoDB, SQLite)
108 | - Auto Dependency Install
109 |
110 | ## Contributing
111 |
112 | See a bug? Want to help? Easiest way is to clone the main repo and run `npm link` in the cloned directory. You can code and then run `create-t3svelte-app` in any directory.
113 |
114 | ```bash
115 | git clone https://github.com/zach-hopkins/create-t3svelte-app
116 | cd create-t3svelte-app
117 | npm i
118 | npm link
119 | mkdir test-project
120 | cd test-project
121 | create-t3svelte-app
122 | ```
123 |
124 | Run `npm unlink create-t3svelte-app` to undo.
125 |
126 | ## Caveats & Addendums
127 |
128 | ### Server-Side Rendering
129 |
130 | If you need to use the tRPC client in SvelteKit's [`load()`](https://kit.svelte.dev/docs/load) function for SSR, make sure to initialize it like so:
131 |
132 | ```ts
133 | // $lib/trpcClient.ts
134 |
135 | import { browser } from '$app/env';
136 | import type { Router } from '$lib/trpcServer';
137 | import * as trpc from '@trpc/client';
138 | import type { LoadEvent } from "@sveltejs/kit";
139 |
140 | const url = browser ? '/trpc' : 'http://localhost:3000/trpc';
141 | export default (loadFetch?: LoadEvent['fetch']) =>
142 | trpc.createTRPCClient({
143 | url: loadFetch ? '/trpc' : url,
144 | transformer: trpcTransformer,
145 | ...(loadFetch && { fetch: loadFetch as typeof fetch })
146 | });
147 |
148 | ```
149 |
150 | Then use it like so:
151 |
152 | ```ts
153 | // src/routes/+authors.svelte
154 |
155 | import trpcClient from '$lib/trpcClient';
156 | import type { Load } from '@sveltejs/kit';
157 |
158 | export const load: Load = async ({ fetch }) => { // 👈 make sure to pass in this fetch, not the global fetch
159 | const authors = await trpcClient(fetch).query('authors:browse', {
160 | genre: 'fantasy',
161 | });
162 | return { props: { authors } };
163 | };
164 | ```
165 |
166 | ### Vercel's Edge Cache for Serverless Functions
167 |
168 | Your server responses must [satisfy some criteria](https://vercel.com/docs/concepts/functions/edge-caching) in order for them to be cached on Vercel's Edge Network. tRPC's `responseMeta()` comes in handy here since you can initialize your handle in [`src/hooks.server.ts`](https://kit.svelte.dev/docs/hooks#server-hooks) like so:
169 |
170 | ```ts
171 | // src/hooks.server.ts
172 |
173 | import { router } from '$lib/trpcServer';
174 | import { createTRPCHandle } from 'trpc-sveltekit';
175 |
176 | export const handle = async ({ event, resolve }) => {
177 | const response = await createTRPCHandle({
178 | url: '/trpc',
179 | event,
180 | resolve,
181 | responseMeta({ type, errors }) {
182 | if (type === 'query' && errors.length === 0) {
183 | const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
184 | return {
185 | headers: {
186 | 'cache-control': `s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS}`
187 | }
188 | };
189 | }
190 | return {};
191 | }
192 | });
193 |
194 | return response;
195 | };
196 | ```
197 |
198 | ## Shoutouts
199 |
200 | - [Theo @ T3](https://t3.gg/) for T3 Stack inspiration!
201 | - [Nexxel](https://github.com/nexxeln) for the OG create-t3-app!
202 | - [Ionut-Cristian Florescu](https://github.com/icflorescu/trpc-sveltekit) for his wonderful work on SvelteKit + tRPC & SSR Info!
203 | - [Ryan Gossiaux](https://github.com/rgossiaux) for enabling TailwindUI & HeadlessUI on Svelte!
204 |
205 | ## License
206 |
207 | [MIT](/LICENSE)
208 |
209 |
--------------------------------------------------------------------------------
/bin/create-t3svelte-app.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | import cli from '../src/cli.js'
3 | cli(process.argv);
--------------------------------------------------------------------------------
/overwrites/mongodb/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | generator client {
2 | provider = "prisma-client-js"
3 | }
4 |
5 | datasource db {
6 | provider = "mongodb"
7 | url = env("DATABASE_URL")
8 | }
9 |
10 | model User {
11 | id String @id @default(auto()) @map("_id") @db.ObjectId
12 | email String @unique
13 | name String?
14 | }
--------------------------------------------------------------------------------
/overwrites/mysql/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | generator client {
2 | provider = "prisma-client-js"
3 | }
4 |
5 | datasource db {
6 | provider = "mysql"
7 | url = env("DATABASE_URL")
8 | }
9 |
10 | model User {
11 | id Int @id @default(autoincrement())
12 | email String @unique
13 | name String?
14 | }
--------------------------------------------------------------------------------
/overwrites/postgres/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | generator client {
2 | provider = "prisma-client-js"
3 | }
4 |
5 | datasource db {
6 | provider = "postgresql"
7 | url = env("DATABASE_URL")
8 | }
9 |
10 | model User {
11 | id Int @id @default(autoincrement())
12 | email String @unique
13 | name String?
14 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "create-t3svelte-app",
3 | "version": "1.1.3",
4 | "description": "Rapidly setup T3 Stack with SvelteKit",
5 | "exports": "./index.js",
6 | "bin": {
7 | "create-t3svelte-app": "bin/create-t3svelte-app.js"
8 | },
9 | "publishConfig": {
10 | "access": "public"
11 | },
12 | "type": "module",
13 | "scripts": {
14 | "test": "echo \"Error: no test specified\" && exit 1"
15 | },
16 | "keywords": [
17 | "cli",
18 | "create-t3svelte-app"
19 | ],
20 | "author": "Zach Hopkins",
21 | "license": "MIT",
22 | "dependencies": {
23 | "arg": "^5.0.2",
24 | "chalk": "^5.0.1",
25 | "execa": "^6.1.0",
26 | "fs-extra": "^10.1.0",
27 | "inquirer": "^9.1.1",
28 | "listr": "^0.14.3",
29 | "pkg-install": "^1.0.0"
30 | },
31 | "devDependencies": {
32 | "prettier": "^2.7.1"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/cli.js:
--------------------------------------------------------------------------------
1 | import arg from 'arg'
2 | import inquirer from 'inquirer'
3 | import { createT3SvelteApp } from './main.js'
4 |
5 | function parseArgumentsIntoOptions(rawArgs) {
6 | const args = arg(
7 | {
8 | '--yes': Boolean,
9 | },
10 | {
11 | argv: rawArgs.slice(2),
12 | }
13 | )
14 | return {
15 | skipPrompts: args['--yes'] || false,
16 | template: args._[0],
17 | }
18 | }
19 |
20 | async function promptForMissingOptions(options) {
21 | const defaultTemplate = 'Standard'
22 | if (options.skipPrompts) {
23 | return {
24 | ...options,
25 | template: options.template || defaultTemplate,
26 | }
27 | }
28 |
29 | const baseQuestion = []
30 | if (!options.template) {
31 | baseQuestion.push({
32 | type: 'list',
33 | name: 'template',
34 | message: 'Please choose which project template to use',
35 | choices: ['Standard', 'Custom: TypeScript', 'Custom: JavaScript'],
36 | default: defaultTemplate,
37 | })
38 | }
39 |
40 | const typeScriptQuestions = []
41 |
42 | typeScriptQuestions.push({
43 | type: 'checkbox',
44 | name: 'options',
45 | message: 'Please choose tech stack options',
46 | choices: [
47 | { name: 'tRPC', checked: true },
48 | { name: 'Prisma ORM', checked: true },
49 | { name: 'Tailwind CSS', checked: true },
50 | ],
51 | })
52 |
53 | const javaScriptQuestions = []
54 |
55 | javaScriptQuestions.push({
56 | type: 'checkbox',
57 | name: 'options',
58 | message: 'Please choose tech stack options',
59 | choices: [
60 | { name: 'Prisma ORM', checked: true },
61 | { name: 'Tailwind CSS', checked: true },
62 | ],
63 | })
64 |
65 | let toolQuestions = []
66 |
67 | toolQuestions.push({
68 | type: 'checkbox',
69 | name: 'options',
70 | message: 'Please choose tech stack options',
71 | choices: [
72 | { name: 'ESLint', checked: true },
73 | { name: 'Prettier', checked: true },
74 | { name: 'Tailwind Prettier', checked: true },
75 | { name: 'Headless UI' },
76 | { name: 'HeroIcons' },
77 | ],
78 | })
79 |
80 | const configQuestions = []
81 | const configQuestionsNoPrisma = []
82 |
83 | configQuestions.push({
84 | type: 'checkbox',
85 | name: 'options',
86 | message: 'Please choose config options',
87 | choices: [
88 | { name: 'Configure database', checked: true },
89 | { name: 'Init .git', checked: true },
90 | { name: 'Auto install dependencies', checked: true },
91 | ],
92 | })
93 |
94 | configQuestionsNoPrisma.push({
95 | type: 'checkbox',
96 | name: 'options',
97 | message: 'Please choose config options',
98 | choices: [
99 | { name: 'Init .git', checked: true },
100 | { name: 'Auto install dependencies', checked: true },
101 | ],
102 | })
103 |
104 | //Inquirer Fork 2 (if needed)
105 | const dbSolutions = []
106 |
107 | dbSolutions.push({
108 | type: 'list',
109 | name: 'dbSolution',
110 | message: 'What DB technology are you using? (first 3 require URI string)',
111 | choices: ['Postgres', 'MySQL', 'MongoDB', 'SQLite', 'Other'],
112 | default: 'Postgres',
113 | })
114 |
115 | //Inquirer Fork 3 (if needed)
116 | const dbQuestions = []
117 |
118 | dbQuestions.push({
119 | type: 'password',
120 | name: 'dbString',
121 | mask: true,
122 | message: 'Enter Full DB URI String',
123 | })
124 |
125 | dbQuestions.push({
126 | type: 'list',
127 | name: 'dbOperation',
128 | message: 'Init new DB schema (blank DB) or import schema from existing DB?',
129 | choices: ['New Schema', 'Import Existing Schema'],
130 | default: 'New Schema',
131 | })
132 |
133 | /* */
134 | /* Process Forks and Prompt Questions */
135 |
136 | const baseTemplate = await inquirer.prompt(baseQuestion) //get base template
137 | let techOptions = []
138 | let toolOptions = []
139 | let requireURI = false
140 | let isStandard = false
141 |
142 | switch (baseTemplate.template) {
143 | case 'Custom: TypeScript':
144 | techOptions = (await inquirer.prompt(typeScriptQuestions)).options
145 | techOptions.push('TypeScript')
146 | break
147 | case 'Custom: JavaScript':
148 | techOptions = (await inquirer.prompt(javaScriptQuestions)).options
149 | techOptions.push('JavaScript')
150 | break
151 | default: //standard
152 | techOptions = ['tRPC', 'Prisma ORM', 'Tailwind CSS', 'TypeScript']
153 | isStandard = true
154 | }
155 |
156 | if (!isStandard) {
157 | if (techOptions.includes('Tailwind CSS'))
158 | toolOptions = (await inquirer.prompt(toolQuestions)).options
159 | //remove tailwind prettier from options
160 | else {
161 | const tailwindPrettierIndex = toolQuestions[0].choices
162 | .map((object) => object.name)
163 | .indexOf('Tailwind Prettier')
164 | toolQuestions[0].choices = [
165 | ...toolQuestions[0].choices.slice(0, tailwindPrettierIndex),
166 | ...toolQuestions[0].choices.slice(tailwindPrettierIndex + 1),
167 | ]
168 | toolOptions = (await inquirer.prompt(toolQuestions)).options
169 | }
170 | } else {
171 | //if Standard
172 | toolOptions = ['ESLint', 'Prettier', 'Tailwind Prettier']
173 | }
174 |
175 | if (techOptions.includes('Prisma ORM'))
176 | var configOptions = (await inquirer.prompt(configQuestions)).options
177 | else var configOptions = (await inquirer.prompt(configQuestionsNoPrisma)).options
178 |
179 | const needsDatabase = configOptions.includes('Configure database') ? true : false
180 | if (needsDatabase) var dbSolutionAnswers = await inquirer.prompt(dbSolutions)
181 |
182 | if (dbSolutionAnswers)
183 | requireURI =
184 | dbSolutionAnswers.dbSolution == 'Postgres' ||
185 | dbSolutionAnswers.dbSolution == 'MySQL' ||
186 | dbSolutionAnswers.dbSolution == 'MongoDB'
187 | ? true
188 | : false
189 |
190 | if (needsDatabase && requireURI) var dbAnswers = await inquirer.prompt(dbQuestions)
191 | //Handle Empty Options
192 | else {
193 | var dbAnswers = {
194 | dbString: 'none',
195 | dbOperation: 'New Schema',
196 | }
197 | }
198 | if (!dbSolutionAnswers) var dbSolutionAnswers = { dbSolution: 'none' }
199 |
200 | //Manage Options
201 | const template = baseTemplate.template
202 |
203 | //Tech Stack
204 | const trpc = techOptions.includes('tRPC')
205 | const prisma = techOptions.includes('Prisma ORM')
206 | const scriptLang = techOptions.includes('TypeScript') ? 'TypeScript' : 'JavaScript'
207 | const tailwind = techOptions.includes('Tailwind CSS')
208 |
209 | //Tooling
210 | const eslint = toolOptions.includes('ESLint')
211 | const prettier = toolOptions.includes('Prettier')
212 | const tailwindPrettier = toolOptions.includes('Tailwind Prettier') && prettier ? true : false
213 | const headlessUI = toolOptions.includes('Headless UI')
214 | const heroIcons = toolOptions.includes('HeroIcons')
215 |
216 | //Configs
217 | const git = configOptions.includes('Init .git')
218 | const runInstall = configOptions.includes('Auto install dependencies')
219 | const db = configOptions.includes('Configure database')
220 |
221 | return {
222 | ...options,
223 | template: options.template || template,
224 |
225 | //Tech Stack
226 | scriptLang: scriptLang,
227 | optionals: {
228 | trpc: trpc,
229 | prisma: prisma,
230 | tailwind: tailwind,
231 |
232 | //Tooling
233 | eslint: eslint,
234 | prettier: prettier,
235 | tailwindPrettier: tailwindPrettier,
236 | headlessUI: headlessUI,
237 | heroIcons: heroIcons,
238 | },
239 | //Configs
240 | git: git,
241 | runInstall: runInstall,
242 | db: db,
243 |
244 | //DB Specific
245 | dbString: dbAnswers.dbString,
246 | dbOperation: dbAnswers.dbOperation,
247 | dbSolution: dbSolutionAnswers.dbSolution,
248 | }
249 | }
250 |
251 | export default async function cli(args) {
252 | let options = parseArgumentsIntoOptions(args)
253 | options = await promptForMissingOptions(options)
254 | await createT3SvelteApp(options)
255 | }
256 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk'
2 | import fs from 'fs-extra'
3 | import path from 'path'
4 | import { promisify } from 'util'
5 | import { execa } from 'execa'
6 | import { fileURLToPath } from 'url'
7 | import Listr from 'listr'
8 | import { projectInstall } from 'pkg-install'
9 | import { exec } from 'child_process'
10 |
11 | const __filename = fileURLToPath(import.meta.url)
12 | const access = promisify(fs.access)
13 |
14 | // CREDIT: https://github.com/t3-oss/create-t3-app/blob/44a107b8d5345023bafc8a773322e5ee39ba8580/cli/src/utils/getUserPkgManager.ts
15 | function getUserPkgManager() {
16 | // This environment variable is set by npm and yarn but pnpm seems less consistent
17 | const userAgent = process.env.npm_config_user_agent;
18 |
19 | if (userAgent) {
20 | if (userAgent.startsWith("yarn")) {
21 | return "yarn";
22 | } else if (userAgent.startsWith("pnpm")) {
23 | return "pnpm";
24 | } else {
25 | return "npm";
26 | }
27 | } else {
28 | // If no user agent is set, assume npm
29 | return "npm";
30 | }
31 | };
32 |
33 | const userPkgManager = getUserPkgManager()
34 | console.log('Using: %s ', chalk.green.bold(userPkgManager))
35 |
36 | async function copyTemplateFiles(options, templateName = 'overwrites', templateBaseDir = '/') {
37 | await fs.copy(options.templateDirectory, options.targetDirectory)
38 | await fs.writeFile(options.targetDirectory + "/.npmrc", "engine-strict=true")
39 | await fs.writeFile(options.targetDirectory + "/.gitignore", ".DS_Store\nnode_modules\n/build\n/.svelte-kit\n/package\n.env")
40 | if (templateName != 'standard' && templateName != 'overwrites') await copyOptionalFiles(options, templateBaseDir)
41 | return
42 | }
43 |
44 | async function copyOptionalFiles(options, templateBaseDir) {
45 | let dirArray = []
46 | let selectedOptionals = []
47 | const scriptLang = options.scriptLang.toLowerCase()
48 |
49 | for (const [key, value] of Object.entries(options.optionals)) {
50 | if (value === true) selectedOptionals.push(key)
51 | }
52 |
53 | /* set dirs for optional additions */
54 |
55 | //Tech Stack
56 | if (selectedOptionals.includes('prisma') && selectedOptionals.includes('trpc'))
57 | dirArray.push(templateBaseDir + '+prisma_trpc')
58 | else if (selectedOptionals.includes('trpc')) dirArray.push(templateBaseDir + '+trpc')
59 | else if (selectedOptionals.includes('prisma')) dirArray.push(templateBaseDir + '+prisma')
60 |
61 | if (selectedOptionals.includes('tailwind')) dirArray.push(templateBaseDir + '+tailwind')
62 |
63 | //Tooling
64 | if (selectedOptionals.includes('eslint') && selectedOptionals.includes('prettier')) {
65 | if (scriptLang == 'typescript') dirArray.push(templateBaseDir + '+eslint_prettier_typescript')
66 | else dirArray.push(templateBaseDir + '+eslint_prettier_javascript')
67 | } else if (selectedOptionals.includes('eslint')) {
68 | if (scriptLang == 'typescript') dirArray.push(templateBaseDir + '+eslint_typescript')
69 | else dirArray.push(templateBaseDir + '+eslint_javascript')
70 | } else if (selectedOptionals.includes('prettier')) dirArray.push(templateBaseDir + '+prettier')
71 |
72 | if (selectedOptionals.includes('heroIcons')) dirArray.push(templateBaseDir + '+heroicons')
73 |
74 | if (selectedOptionals.includes('headlessUI')) dirArray.push(templateBaseDir + '+headlessui')
75 |
76 | if (selectedOptionals.includes('tailwindPrettier'))
77 | dirArray.push(templateBaseDir + '+tailwind_prettier_plugin')
78 |
79 | const npmCommands = await compileInstalls(dirArray)
80 |
81 | for (let urlIndex in dirArray) {
82 | fs.copySync(dirArray[urlIndex], options.targetDirectory)
83 | }
84 |
85 | for (let commandIndex in npmCommands) {
86 | await new Promise(function(resolve, reject) {
87 | exec(npmCommands[commandIndex], (err, stdout, stderr) => {
88 | if (err) {
89 | reject(err)
90 | } else {
91 | resolve({ stdout, stderr })
92 | }
93 | })
94 | })
95 | }
96 |
97 | //cleanup package.txt
98 | fs.removeSync(options.targetDirectory + '/package.txt')
99 |
100 | return
101 | }
102 |
103 | async function compileInstalls(dirArray) {
104 | //read package.txt for each optional package to configure package.json
105 | let npmCommands = []
106 | for (let urlIndex in dirArray) {
107 | let lines = fs.readFileSync(dirArray[urlIndex] + '/package.txt', 'utf8').replace('\n', '')
108 | if (userPkgManager === 'pnpm') {
109 | lines = lines
110 | .replace(/npm/g, 'pnpm')
111 | .replace(/--no-package-lock /g, '')
112 | .replace(/--package-lock-only/g, '--lockfile-only')
113 | } else if (userPkgManager === 'yarn') {
114 | lines = lines
115 | .replace(/npm install/g, 'yarn add')
116 | .replace(/--no-package-lock /g, '')
117 | .replace(/--package-lock-only/g, '--mode update-lockfile')
118 | }
119 | npmCommands.push(lines)
120 | }
121 | return npmCommands
122 | }
123 |
124 | async function configureDatabase(options) {
125 | await copyEnvFile(options)
126 | const operation = options.dbOperation == 'Import Existing Schema' ? 'pull' : 'push'
127 | const basePath = options.templateDirectory.split('/templates')[0]
128 | const overwriteFolder = options.dbSolution.toLowerCase()
129 | const customOptions = {
130 | targetDirectory: options.targetDirectory,
131 | templateDirectory: basePath + '/overwrites/' + overwriteFolder
132 | }
133 |
134 | const overwriteRequired = ['postgres', 'mysql', 'mongodb'] //add DBs requiring overwrite here
135 | if (overwriteRequired.includes(overwriteFolder)) //guard clause to only overwrite when needed (Postgres, mySQL, mongodb etc)
136 | await copyTemplateFiles(customOptions)
137 |
138 | const resultPull = await execa('npx', ['prisma', 'db', operation], {
139 | cwd: options.targetDirectory,
140 | })
141 | if (operation == 'pull') {
142 | const resultGenerate = await execa('npx', ['prisma', 'generate'], {
143 | cwd: options.targetDirectory,
144 | })
145 | if (resultGenerate.failed) return Promise.reject(new Error('Failed to intialize DB via Prisma'))
146 | }
147 | if (resultPull.failed) {
148 | return Promise.reject(new Error('Failed to intialize DB via Prisma'))
149 | }
150 | return
151 | }
152 |
153 | async function copyEnvFile(options) {
154 | const content = `DATABASE_URL="${options.dbString}"`
155 | const file = options.targetDirectory + '/.env'
156 | fs.writeFile(file, content, function(err) {
157 | if (err) {
158 | throw err
159 | }
160 | return
161 | })
162 | }
163 |
164 | async function initGit(options) {
165 | const result = await execa('git', ['init'], {
166 | cwd: options.targetDirectory,
167 | })
168 |
169 | if (result.failed) {
170 | console.log('Failed to init git')
171 | return Promise.reject(new Error('Failed to initialize git'))
172 | }
173 | return
174 | }
175 |
176 | export async function createT3SvelteApp(options) {
177 | options = {
178 | ...options,
179 | targetDirectory: options.targetDirectory || process.cwd(),
180 | }
181 | const templateBaseDir = path.resolve(__filename, '../../templates')
182 | const templateName = options.template.toLowerCase()
183 | let templateDir = ''
184 |
185 | if (templateName == 'standard') templateDir = templateBaseDir + '/standard'
186 | else if (templateName == 'custom: typescript') templateDir = templateBaseDir + '/base_typescript'
187 | else templateDir = templateBaseDir + '/base_javascript'
188 |
189 | options.templateDirectory = templateDir
190 |
191 | try {
192 | await access(templateDir, fs.constants.R_OK)
193 | } catch (err) {
194 | console.log(templateDir)
195 | console.error('%s Invalid template name', chalk.red.bold('ERROR'))
196 | process.exit(1)
197 | }
198 |
199 | const tasks = new Listr([
200 | {
201 | title: 'Copy project files',
202 | task: () => copyTemplateFiles(options, templateName, templateBaseDir + '/'),
203 | },
204 | {
205 | title: 'Initialize git',
206 | task: () => initGit(options),
207 | enabled: () => options.git,
208 | },
209 | {
210 | title: 'Install dependencies',
211 | task: () => {
212 | projectInstall({
213 | prefer: userPkgManager,
214 | cwd: options.targetDirectory,
215 | })
216 | },
217 | enabled: () => options.runInstall,
218 | },
219 | {
220 | title: 'Initialize DB',
221 | task: () => configureDatabase(options),
222 | enabled: () => options.db,
223 | },
224 | ])
225 |
226 | await tasks.run()
227 | console.log('%s SvelteT3 is ready!', chalk.green.bold('DONE'))
228 | return true
229 | }
230 |
--------------------------------------------------------------------------------
/templates/+eslint_javascript/.eslintignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/templates/+eslint_javascript/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: ['eslint:recommended'],
4 | plugins: ['svelte3'],
5 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
6 | parserOptions: {
7 | sourceType: 'module',
8 | ecmaVersion: 2020
9 | },
10 | env: {
11 | browser: true,
12 | es2017: true,
13 | node: true
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/templates/+eslint_javascript/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save -D --package-lock-only --no-package-lock eslint eslint-plugin-svelte3
--------------------------------------------------------------------------------
/templates/+eslint_prettier_javascript/.eslintignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/templates/+eslint_prettier_javascript/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: ['eslint:recommended', 'prettier'],
4 | plugins: ['svelte3'],
5 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
6 | parserOptions: {
7 | sourceType: 'module',
8 | ecmaVersion: 2020
9 | },
10 | env: {
11 | browser: true,
12 | es2017: true,
13 | node: true
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/templates/+eslint_prettier_javascript/.prettierignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/templates/+eslint_prettier_javascript/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": true,
3 | "singleQuote": true,
4 | "tabWidth": 2,
5 | "trailingComma": "es5",
6 | "printWidth": 100,
7 | "pluginSearchDirs": ["."],
8 | "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
9 | }
10 |
--------------------------------------------------------------------------------
/templates/+eslint_prettier_javascript/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save -D --package-lock-only --no-package-lock eslint eslint-plugin-svelte3 prettier prettier-plugin-svelte eslint-config-prettier
--------------------------------------------------------------------------------
/templates/+eslint_prettier_typescript/.eslintignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/templates/+eslint_prettier_typescript/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: '@typescript-eslint/parser',
4 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
5 | plugins: ['svelte3', '@typescript-eslint'],
6 | ignorePatterns: ['*.cjs'],
7 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
8 | settings: {
9 | 'svelte3/typescript': () => require('typescript')
10 | },
11 | parserOptions: {
12 | sourceType: 'module',
13 | ecmaVersion: 2020
14 | },
15 | env: {
16 | browser: true,
17 | es2017: true,
18 | node: true
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/templates/+eslint_prettier_typescript/.prettierignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/templates/+eslint_prettier_typescript/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": true,
3 | "singleQuote": true,
4 | "tabWidth": 2,
5 | "trailingComma": "es5",
6 | "printWidth": 100,
7 | "pluginSearchDirs": ["."],
8 | "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
9 | }
10 |
--------------------------------------------------------------------------------
/templates/+eslint_prettier_typescript/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save -D --package-lock-only --no-package-lock prettier prettier-plugin-svelte eslint eslint-plugin-svelte3 @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-prettier
--------------------------------------------------------------------------------
/templates/+eslint_typescript/.eslintignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/templates/+eslint_typescript/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: '@typescript-eslint/parser',
4 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
5 | plugins: ['svelte3', '@typescript-eslint'],
6 | ignorePatterns: ['*.cjs'],
7 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
8 | settings: {
9 | 'svelte3/typescript': () => require('typescript')
10 | },
11 | parserOptions: {
12 | sourceType: 'module',
13 | ecmaVersion: 2020
14 | },
15 | env: {
16 | browser: true,
17 | es2017: true,
18 | node: true
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/templates/+eslint_typescript/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save -D --package-lock-only --no-package-lock eslint eslint-plugin-svelte3 @typescript-eslint/parser @typescript-eslint/eslint-plugin
--------------------------------------------------------------------------------
/templates/+headlessui/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save -D --package-lock-only --no-package-lock @rgossiaux/svelte-headlessui
--------------------------------------------------------------------------------
/templates/+heroicons/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save -D --package-lock-only --no-package-lock @rgossiaux/svelte-heroicons
--------------------------------------------------------------------------------
/templates/+prettier/.prettierignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/templates/+prettier/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": true,
3 | "singleQuote": true,
4 | "tabWidth": 2,
5 | "trailingComma": "es5",
6 | "printWidth": 100,
7 | "pluginSearchDirs": ["."],
8 | "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
9 | }
10 |
--------------------------------------------------------------------------------
/templates/+prettier/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save -D --package-lock-only --no-package-lock prettier prettier-plugin-svelte
--------------------------------------------------------------------------------
/templates/+prisma/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save -D --package-lock-only --no-package-lock prisma @prisma/client
2 |
--------------------------------------------------------------------------------
/templates/+prisma/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | generator client {
2 | provider = "prisma-client-js"
3 | }
4 |
5 | datasource db {
6 | provider = "sqlite"
7 | url = "file:./main.db"
8 | //url = env("DATABASE_URL")
9 | }
10 |
11 | model User {
12 | id Int @id @default(autoincrement())
13 | email String @unique
14 | name String?
15 | }
--------------------------------------------------------------------------------
/templates/+prisma/src/lib/server/prismaClient.ts:
--------------------------------------------------------------------------------
1 | import pkg from '@prisma/client';
2 | const { PrismaClient } = pkg;
3 |
4 | const prismaClient = new PrismaClient();
5 | export default prismaClient;
6 |
--------------------------------------------------------------------------------
/templates/+prisma_trpc/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save --package-lock-only --no-package-lock @trpc/client@"^9.27.2" @trpc/server@"^9.27.2" trpc-sveltekit trpc-transformer zod && npm install --save -D --package-lock-only --no-package-lock @prisma/client prisma
2 |
--------------------------------------------------------------------------------
/templates/+prisma_trpc/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | generator client {
2 | provider = "prisma-client-js"
3 | }
4 |
5 | datasource db {
6 | provider = "sqlite"
7 | url = "file:./main.db"
8 | //url = env("DATABASE_URL")
9 | }
10 |
11 | model User {
12 | id Int @id @default(autoincrement())
13 | email String @unique
14 | name String?
15 | }
--------------------------------------------------------------------------------
/templates/+prisma_trpc/src/hooks.server.ts:
--------------------------------------------------------------------------------
1 | import type { Handle } from '@sveltejs/kit'
2 | import { createContext, responseMeta, router } from '$lib/server/trpcServer'
3 | import { createTRPCHandle } from 'trpc-sveltekit'
4 |
5 | export const handle: Handle = async ({ event, resolve }) => {
6 | const response = await createTRPCHandle({
7 | url: '/trpc', // optional; defaults to '/trpc'
8 | router,
9 | createContext, // optional
10 | responseMeta, // optional
11 | event,
12 | resolve,
13 | })
14 |
15 | return response
16 | }
17 |
--------------------------------------------------------------------------------
/templates/+prisma_trpc/src/lib/client/trpc.ts:
--------------------------------------------------------------------------------
1 | import type { Router } from '$lib/server/trpcServer' // 👈 only the types are imported from the server
2 | import * as trpc from '@trpc/client'
3 | import trpcTransformer from 'trpc-transformer'
4 | import type { inferProcedureInput, inferProcedureOutput } from '@trpc/server'
5 |
6 | const url = '/trpc'
7 |
8 | export default (loadFetch?: typeof fetch) =>
9 | trpc.createTRPCClient({
10 | url: loadFetch ? '/trpc' : url,
11 | transformer: trpcTransformer,
12 | ...(loadFetch && { fetch: loadFetch }),
13 | })
14 |
15 | type Query = keyof Router['_def']['queries']
16 | type Mutation = keyof Router['_def']['mutations']
17 |
18 | export type InferQueryOutput = inferProcedureOutput<
19 | Router['_def']['queries'][RouteKey]
20 | >
21 | export type InferQueryInput = inferProcedureInput<
22 | Router['_def']['queries'][RouteKey]
23 | >
24 | export type InferMutationOutput = inferProcedureOutput<
25 | Router['_def']['mutations'][RouteKey]
26 | >
27 | export type InferMutationInput = inferProcedureInput<
28 | Router['_def']['mutations'][RouteKey]
29 | >
30 |
--------------------------------------------------------------------------------
/templates/+prisma_trpc/src/lib/server/prismaClient.ts:
--------------------------------------------------------------------------------
1 | import pkg from '@prisma/client';
2 | const { PrismaClient } = pkg;
3 |
4 | const prismaClient = new PrismaClient();
5 | export default prismaClient;
6 |
--------------------------------------------------------------------------------
/templates/+prisma_trpc/src/lib/server/trpcServer.ts:
--------------------------------------------------------------------------------
1 | import type { inferAsyncReturnType } from '@trpc/server'
2 | import * as trpc from '@trpc/server'
3 | import trpcTransformer from 'trpc-transformer'
4 | import prismaClient from './prismaClient'
5 | import { z } from 'zod'
6 |
7 | // optional
8 | export const createContext = () => {
9 | // ...
10 | return {
11 | /** context data */
12 | }
13 | }
14 |
15 | // optional
16 | export const responseMeta = () => {
17 | // ...
18 | return {
19 | // { headers: ... }
20 | }
21 | }
22 |
23 | export const router = trpc
24 | .router>()
25 | .transformer(trpcTransformer)
26 | // queries and mutations...
27 | .query('getUser', {
28 | input: z.number(),
29 | resolve: ({ input }) =>
30 | prismaClient.user.findFirst({
31 | select: {
32 | email: true,
33 | },
34 | where: {
35 | id: input,
36 | },
37 | }),
38 | })
39 |
40 | export type Router = typeof router
41 |
--------------------------------------------------------------------------------
/templates/+tailwind/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save -D --package-lock-only --no-package-lock postcss autoprefixer tailwindcss @tailwindcss/forms
--------------------------------------------------------------------------------
/templates/+tailwind/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/templates/+tailwind/src/app.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
--------------------------------------------------------------------------------
/templates/+tailwind/src/routes/+layout.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/templates/+tailwind/svelte.config.js:
--------------------------------------------------------------------------------
1 | import adapter from '@sveltejs/adapter-auto'
2 | import preprocess from 'svelte-preprocess'
3 |
4 | /** @type {import('@sveltejs/kit').Config} */
5 | const config = {
6 | // Consult https://github.com/sveltejs/svelte-preprocess
7 | // for more information about preprocessors
8 | preprocess: preprocess({
9 | postcss: true,
10 | }),
11 | kit: {
12 | adapter: adapter(),
13 | },
14 | }
15 |
16 | export default config
17 |
--------------------------------------------------------------------------------
/templates/+tailwind/tailwind.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: ['./src/**/*.{html,js,svelte,ts}'],
4 | theme: {
5 | extend: {}
6 | },
7 | plugins: [require('@tailwindcss/forms')]
8 | };
9 |
--------------------------------------------------------------------------------
/templates/+tailwind_prettier_plugin/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save -D --package-lock-only --no-package-lock prettier-plugin-tailwindcss
--------------------------------------------------------------------------------
/templates/+trpc/package.txt:
--------------------------------------------------------------------------------
1 | npm install --save --package-lock-only --no-package-lock @trpc/client@"^9.27.2" @trpc/server@"^9.27.2" trpc-sveltekit trpc-transformer zod
2 |
--------------------------------------------------------------------------------
/templates/+trpc/src/hooks.server.ts:
--------------------------------------------------------------------------------
1 | import type { Handle } from '@sveltejs/kit'
2 | import { createContext, responseMeta, router } from '$lib/server/trpcServer'
3 | import { createTRPCHandle } from 'trpc-sveltekit'
4 |
5 | export const handle: Handle = async ({ event, resolve }) => {
6 | const response = await createTRPCHandle({
7 | url: '/trpc', // optional; defaults to '/trpc'
8 | router,
9 | createContext, // optional
10 | responseMeta, // optional
11 | event,
12 | resolve,
13 | })
14 |
15 | return response
16 | }
17 |
--------------------------------------------------------------------------------
/templates/+trpc/src/lib/client/trpc.ts:
--------------------------------------------------------------------------------
1 | import type { Router } from '$lib/server/trpcServer' // 👈 only the types are imported from the server
2 | import * as trpc from '@trpc/client'
3 | import trpcTransformer from 'trpc-transformer'
4 | import type { inferProcedureInput, inferProcedureOutput } from '@trpc/server'
5 |
6 | const url = '/trpc'
7 |
8 | export default (loadFetch?: typeof fetch) =>
9 | trpc.createTRPCClient({
10 | url: loadFetch ? '/trpc' : url,
11 | transformer: trpcTransformer,
12 | ...(loadFetch && { fetch: loadFetch }),
13 | })
14 |
15 | type Query = keyof Router['_def']['queries']
16 | type Mutation = keyof Router['_def']['mutations']
17 |
18 | export type InferQueryOutput = inferProcedureOutput<
19 | Router['_def']['queries'][RouteKey]
20 | >
21 | export type InferQueryInput = inferProcedureInput<
22 | Router['_def']['queries'][RouteKey]
23 | >
24 | export type InferMutationOutput = inferProcedureOutput<
25 | Router['_def']['mutations'][RouteKey]
26 | >
27 | export type InferMutationInput = inferProcedureInput<
28 | Router['_def']['mutations'][RouteKey]
29 | >
30 |
--------------------------------------------------------------------------------
/templates/+trpc/src/lib/server/trpcServer.ts:
--------------------------------------------------------------------------------
1 | //import prismaClient from './prismaClient'
2 | import type { inferAsyncReturnType } from '@trpc/server'
3 | import * as trpc from '@trpc/server'
4 | import trpcTransformer from 'trpc-transformer'
5 | import { z } from 'zod'
6 |
7 | // optional
8 | export const createContext = () => {
9 | // ...
10 | return {
11 | /** context data */
12 | }
13 | }
14 |
15 | // optional
16 | export const responseMeta = () => {
17 | // ...
18 | return {
19 | // { headers: ... }
20 | }
21 | }
22 |
23 | export const router = trpc
24 | .router>()
25 | .transformer(trpcTransformer)
26 | // queries and mutations...
27 | .query('getUser', {
28 | input: z.number(),
29 | resolve: ({ input }) =>
30 | // prismaClient.user.findFirst({
31 | // select: {
32 | // email: true,
33 | // },
34 | // where: {
35 | // id: input,
36 | // },
37 | // }),
38 | })
39 |
40 | export type Router = typeof router
41 |
--------------------------------------------------------------------------------
/templates/base_javascript/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
--------------------------------------------------------------------------------
/templates/base_javascript/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 |
--------------------------------------------------------------------------------
/templates/base_javascript/README.md:
--------------------------------------------------------------------------------
1 | # T3Svelte Starter Project
2 |
3 | \*SvelteKit
4 |
5 | \*Typescript
6 |
7 | \*tRPC
8 |
9 | \*Prisma
10 |
11 | \*Tailwind CSS (@forms | @heroicons | @headlessui configured for Tailwind UI)
12 |
13 | \*Prettier + Prettier Tailwind + ESLint Preconfigured
14 |
--------------------------------------------------------------------------------
/templates/base_javascript/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.svelte-kit/tsconfig.json",
3 | "compilerOptions": {
4 | "allowJs": true,
5 | "checkJs": true,
6 | "esModuleInterop": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "resolveJsonModule": true,
9 | "skipLibCheck": true,
10 | "sourceMap": true,
11 | "strict": true
12 | }
13 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files
14 | //
15 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
16 | // from the referenced tsconfig.json - TypeScript does not merge them in
17 | }
18 |
--------------------------------------------------------------------------------
/templates/base_javascript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "t3svelte-app",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "dev": "vite dev",
7 | "build": "vite build",
8 | "preview": "vite preview",
9 | "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
10 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
11 | "lint": "prettier --check . && eslint .",
12 | "format": "prettier --write ."
13 | },
14 | "devDependencies": {
15 | "@sveltejs/adapter-auto": "next",
16 | "@sveltejs/kit": "next",
17 | "svelte": "^3.44.0",
18 | "svelte-check": "^2.7.1",
19 | "svelte-preprocess": "^4.10.7",
20 | "typescript": "^4.7.4",
21 | "vite": "^4.0.0"
22 | },
23 | "type": "module",
24 | "dependencies": {
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/templates/base_javascript/src/app.d.ts:
--------------------------------------------------------------------------------
1 | // See https://kit.svelte.dev/docs/types#app
2 | // for information about these interfaces
3 | // and what to do when importing types
4 | declare namespace App {
5 | // interface Locals {}
6 | // interface PageData {}
7 | // interface Platform {}
8 | }
9 |
--------------------------------------------------------------------------------
/templates/base_javascript/src/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | %sveltekit.head%
8 |
9 |
10 | %sveltekit.body%
11 |
12 |
13 |
--------------------------------------------------------------------------------
/templates/base_javascript/src/routes/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |

13 |
14 | Welcome to T3 SvelteKit
15 |
--------------------------------------------------------------------------------
/templates/base_javascript/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zach-hopkins/create-t3svelte-app/52e10122a2349bb4d2f5cbd1e16217ba08146966/templates/base_javascript/static/favicon.png
--------------------------------------------------------------------------------
/templates/base_javascript/svelte.config.js:
--------------------------------------------------------------------------------
1 | import adapter from '@sveltejs/adapter-auto'
2 | import preprocess from 'svelte-preprocess'
3 |
4 | /** @type {import('@sveltejs/kit').Config} */
5 | const config = {
6 | // Consult https://github.com/sveltejs/svelte-preprocess
7 | // for more information about preprocessors
8 | preprocess: preprocess({
9 | }),
10 | kit: {
11 | adapter: adapter(),
12 | },
13 | }
14 |
15 | export default config
16 |
--------------------------------------------------------------------------------
/templates/base_javascript/vite.config.js:
--------------------------------------------------------------------------------
1 | import { sveltekit } from '@sveltejs/kit/vite';
2 |
3 | /** @type {import('vite').UserConfig} */
4 | const config = {
5 | plugins: [sveltekit()]
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/templates/base_typescript/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
--------------------------------------------------------------------------------
/templates/base_typescript/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 |
--------------------------------------------------------------------------------
/templates/base_typescript/README.md:
--------------------------------------------------------------------------------
1 | # T3Svelte Starter Project
2 |
3 | *SvelteKit
4 |
5 | *Typescript
6 |
7 | *tRPC
8 |
9 | *Prisma
10 |
11 | *Tailwind CSS (@forms | @heroicons | @headlessui configured for Tailwind UI)
12 |
13 | *Prettier + Prettier Tailwind + ESLint Preconfigured
14 |
--------------------------------------------------------------------------------
/templates/base_typescript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "t3svelte-app",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "dev": "vite dev",
7 | "build": "vite build",
8 | "preview": "vite preview",
9 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
10 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
11 | "lint": "prettier --check . && eslint .",
12 | "format": "prettier --write ."
13 | },
14 | "devDependencies": {
15 | "@sveltejs/adapter-auto": "next",
16 | "@sveltejs/kit": "next",
17 | "svelte": "^3.44.0",
18 | "svelte-check": "^2.7.1",
19 | "svelte-preprocess": "^4.10.7",
20 | "tslib": "^2.3.1",
21 | "typescript": "^4.7.4",
22 | "vite": "^4.0.0"
23 | },
24 | "type": "module",
25 | "dependencies": {
26 | }
27 | }
--------------------------------------------------------------------------------
/templates/base_typescript/src/app.d.ts:
--------------------------------------------------------------------------------
1 | // See https://kit.svelte.dev/docs/types#app
2 | // for information about these interfaces
3 | // and what to do when importing types
4 | declare namespace App {
5 | // interface Locals {}
6 | // interface PageData {}
7 | // interface Platform {}
8 | }
9 |
--------------------------------------------------------------------------------
/templates/base_typescript/src/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | %sveltekit.head%
8 |
9 |
10 | %sveltekit.body%
11 |
12 |
13 |
--------------------------------------------------------------------------------
/templates/base_typescript/src/routes/+page.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |

19 |
20 | Welcome to T3 SvelteKit
--------------------------------------------------------------------------------
/templates/base_typescript/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zach-hopkins/create-t3svelte-app/52e10122a2349bb4d2f5cbd1e16217ba08146966/templates/base_typescript/static/favicon.png
--------------------------------------------------------------------------------
/templates/base_typescript/svelte.config.js:
--------------------------------------------------------------------------------
1 | import adapter from '@sveltejs/adapter-auto'
2 | import preprocess from 'svelte-preprocess'
3 |
4 | /** @type {import('@sveltejs/kit').Config} */
5 | const config = {
6 | // Consult https://github.com/sveltejs/svelte-preprocess
7 | // for more information about preprocessors
8 | preprocess: preprocess({
9 | }),
10 | kit: {
11 | adapter: adapter(),
12 | },
13 | }
14 |
15 | export default config
16 |
--------------------------------------------------------------------------------
/templates/base_typescript/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.svelte-kit/tsconfig.json",
3 | "compilerOptions": {
4 | "allowJs": true,
5 | "checkJs": true,
6 | "esModuleInterop": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "resolveJsonModule": true,
9 | "skipLibCheck": true,
10 | "sourceMap": true,
11 | "strict": true
12 | }
13 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
14 | //
15 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
16 | // from the referenced tsconfig.json - TypeScript does not merge them in
17 | }
18 |
--------------------------------------------------------------------------------
/templates/base_typescript/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { sveltekit } from '@sveltejs/kit/vite';
2 | import type { UserConfig } from 'vite';
3 |
4 | const config: UserConfig = {
5 | plugins: [sveltekit()]
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/templates/standard/.eslintignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/templates/standard/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: '@typescript-eslint/parser',
4 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
5 | plugins: ['svelte3', '@typescript-eslint'],
6 | ignorePatterns: ['*.cjs'],
7 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
8 | settings: {
9 | 'svelte3/typescript': () => require('typescript')
10 | },
11 | parserOptions: {
12 | sourceType: 'module',
13 | ecmaVersion: 2020
14 | },
15 | env: {
16 | browser: true,
17 | es2017: true,
18 | node: true
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/templates/standard/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
--------------------------------------------------------------------------------
/templates/standard/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 |
--------------------------------------------------------------------------------
/templates/standard/.prettierignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/templates/standard/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": true,
3 | "singleQuote": true,
4 | "tabWidth": 2,
5 | "trailingComma": "es5",
6 | "semi": false,
7 | "bracketSameLine": true,
8 | "printWidth": 100,
9 | "pluginSearchDirs": ["."],
10 | "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
11 | }
12 |
--------------------------------------------------------------------------------
/templates/standard/README.md:
--------------------------------------------------------------------------------
1 | # T3Svelte Starter Project
2 |
3 | *SvelteKit
4 |
5 | *Typescript
6 |
7 | *tRPC
8 |
9 | *Prisma
10 |
11 | *Tailwind CSS (@forms | @heroicons | @headlessui configured for Tailwind UI)
12 |
13 | *Prettier + Prettier Tailwind + ESLint Preconfigured
14 |
--------------------------------------------------------------------------------
/templates/standard/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "t3svelte-app",
3 | "version": "0.0.1",
4 | "scripts": {
5 | "dev": "vite dev",
6 | "build": "vite build",
7 | "preview": "vite preview",
8 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
9 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
10 | "lint": "prettier --check . && eslint .",
11 | "format": "prettier --write ."
12 | },
13 | "devDependencies": {
14 | "@rgossiaux/svelte-heroicons": "^0.1.2",
15 | "@sveltejs/adapter-auto": "next",
16 | "@sveltejs/kit": "next",
17 | "@typescript-eslint/eslint-plugin": "^5.27.0",
18 | "@typescript-eslint/parser": "^5.27.0",
19 | "autoprefixer": "^10.4.8",
20 | "eslint": "^8.16.0",
21 | "eslint-config-prettier": "^8.3.0",
22 | "eslint-plugin-svelte3": "^4.0.0",
23 | "postcss": "^8.4.16",
24 | "prettier": "^2.6.2",
25 | "prettier-plugin-svelte": "^2.7.0",
26 | "prettier-plugin-tailwindcss": "^0.1.13",
27 | "prisma": "^4.3.1",
28 | "svelte": "^3.44.0",
29 | "svelte-check": "^2.7.1",
30 | "svelte-preprocess": "^4.10.7",
31 | "tailwindcss": "^3.1.8",
32 | "tslib": "^2.3.1",
33 | "typescript": "^4.7.4",
34 | "vite": "^4.0.0",
35 | "@tailwindcss/forms": "^0.5.3",
36 | "@rgossiaux/svelte-headlessui": "^1.0.2"
37 | },
38 | "type": "module",
39 | "dependencies": {
40 | "@prisma/client": "^4.3.1",
41 | "@trpc/client": "^9.27.2",
42 | "@trpc/server": "^9.27.2",
43 | "trpc-sveltekit": "^2.3.2",
44 | "trpc-transformer": "^2.1.1",
45 | "zod": "^3.19.0"
46 | }
47 | }
--------------------------------------------------------------------------------
/templates/standard/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/templates/standard/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | generator client {
2 | provider = "prisma-client-js"
3 | }
4 |
5 | datasource db {
6 | provider = "sqlite"
7 | url = "file:./main.db"
8 | //url = env("DATABASE_URL")
9 | }
10 |
11 | model User {
12 | id Int @id @default(autoincrement())
13 | email String @unique
14 | name String?
15 | }
--------------------------------------------------------------------------------
/templates/standard/src/app.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
--------------------------------------------------------------------------------
/templates/standard/src/app.d.ts:
--------------------------------------------------------------------------------
1 | // See https://kit.svelte.dev/docs/types#app
2 | // for information about these interfaces
3 | // and what to do when importing types
4 | declare namespace App {
5 | // interface Locals {}
6 | // interface PageData {}
7 | // interface Platform {}
8 | }
9 |
--------------------------------------------------------------------------------
/templates/standard/src/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | %sveltekit.head%
8 |
9 |
10 | %sveltekit.body%
11 |
12 |
13 |
--------------------------------------------------------------------------------
/templates/standard/src/hooks.server.ts:
--------------------------------------------------------------------------------
1 | import type { Handle } from '@sveltejs/kit'
2 | import { createContext, responseMeta, router } from '$lib/server/trpcServer'
3 | import { createTRPCHandle } from 'trpc-sveltekit'
4 |
5 | export const handle: Handle = async ({ event, resolve }) => {
6 | const response = await createTRPCHandle({
7 | url: '/trpc', // optional; defaults to '/trpc'
8 | router,
9 | createContext, // optional
10 | responseMeta, // optional
11 | event,
12 | resolve,
13 | })
14 |
15 | return response
16 | }
17 |
--------------------------------------------------------------------------------
/templates/standard/src/lib/client/trpc.ts:
--------------------------------------------------------------------------------
1 | import type { Router } from '$lib/server/trpcServer' // 👈 only the types are imported from the server
2 | import * as trpc from '@trpc/client'
3 | import trpcTransformer from 'trpc-transformer'
4 | import type { inferProcedureInput, inferProcedureOutput } from '@trpc/server'
5 |
6 | const url = '/trpc'
7 |
8 | export default (loadFetch?: typeof fetch) =>
9 | trpc.createTRPCClient({
10 | url: loadFetch ? '/trpc' : url,
11 | transformer: trpcTransformer,
12 | ...(loadFetch && { fetch: loadFetch }),
13 | })
14 |
15 | type Query = keyof Router['_def']['queries']
16 | type Mutation = keyof Router['_def']['mutations']
17 |
18 | export type InferQueryOutput = inferProcedureOutput<
19 | Router['_def']['queries'][RouteKey]
20 | >
21 | export type InferQueryInput = inferProcedureInput<
22 | Router['_def']['queries'][RouteKey]
23 | >
24 | export type InferMutationOutput = inferProcedureOutput<
25 | Router['_def']['mutations'][RouteKey]
26 | >
27 | export type InferMutationInput = inferProcedureInput<
28 | Router['_def']['mutations'][RouteKey]
29 | >
30 |
--------------------------------------------------------------------------------
/templates/standard/src/lib/server/prismaClient.ts:
--------------------------------------------------------------------------------
1 | import pkg from '@prisma/client';
2 | const { PrismaClient } = pkg;
3 |
4 | const prismaClient = new PrismaClient();
5 | export default prismaClient;
6 |
--------------------------------------------------------------------------------
/templates/standard/src/lib/server/trpcServer.ts:
--------------------------------------------------------------------------------
1 | import type { inferAsyncReturnType } from '@trpc/server'
2 | import * as trpc from '@trpc/server'
3 | import trpcTransformer from 'trpc-transformer'
4 | import prismaClient from './prismaClient'
5 | import { z } from 'zod'
6 |
7 | // optional
8 | export const createContext = () => {
9 | // ...
10 | return {
11 | /** context data */
12 | }
13 | }
14 |
15 | // optional
16 | export const responseMeta = () => {
17 | // ...
18 | return {
19 | // { headers: ... }
20 | }
21 | }
22 |
23 | export const router = trpc
24 | .router>()
25 | .transformer(trpcTransformer)
26 | // queries and mutations...
27 | .query('getUser', {
28 | input: z.number(),
29 | resolve: ({ input }) =>
30 | prismaClient.user.findFirst({
31 | select: {
32 | email: true,
33 | },
34 | where: {
35 | id: input,
36 | },
37 | }),
38 | })
39 |
40 | export type Router = typeof router
41 |
--------------------------------------------------------------------------------
/templates/standard/src/routes/+layout.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/templates/standard/src/routes/+page.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |

19 |
20 | Welcome to T3 SvelteKit
--------------------------------------------------------------------------------
/templates/standard/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zach-hopkins/create-t3svelte-app/52e10122a2349bb4d2f5cbd1e16217ba08146966/templates/standard/static/favicon.png
--------------------------------------------------------------------------------
/templates/standard/svelte.config.js:
--------------------------------------------------------------------------------
1 | import adapter from '@sveltejs/adapter-auto'
2 | import preprocess from 'svelte-preprocess'
3 |
4 | /** @type {import('@sveltejs/kit').Config} */
5 | const config = {
6 | // Consult https://github.com/sveltejs/svelte-preprocess
7 | // for more information about preprocessors
8 | preprocess: preprocess({
9 | }),
10 | kit: {
11 | adapter: adapter(),
12 | },
13 | }
14 |
15 | export default config
16 |
--------------------------------------------------------------------------------
/templates/standard/tailwind.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: ['./src/**/*.{html,js,svelte,ts}'],
4 | theme: {
5 | extend: {}
6 | },
7 | plugins: [require('@tailwindcss/forms')]
8 | };
9 |
--------------------------------------------------------------------------------
/templates/standard/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.svelte-kit/tsconfig.json",
3 | "compilerOptions": {
4 | "allowJs": true,
5 | "checkJs": true,
6 | "esModuleInterop": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "resolveJsonModule": true,
9 | "skipLibCheck": true,
10 | "sourceMap": true,
11 | "strict": true
12 | }
13 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
14 | //
15 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
16 | // from the referenced tsconfig.json - TypeScript does not merge them in
17 | }
18 |
--------------------------------------------------------------------------------
/templates/standard/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { sveltekit } from '@sveltejs/kit/vite';
2 | import type { UserConfig } from 'vite';
3 |
4 | const config: UserConfig = {
5 | plugins: [sveltekit()]
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------