SvelteKit & Prisma - A match made in digital heaven
Key Takeaways
- Most production applications need to persist & retrieve data. Prisma is a pretty genius way to achieve that.
- With SvelteKit, you get client & server-side data fetching - the best of both worlds.
- This all even works if JavaScript is disabled in the browser.
- Template GitHub repo: https://github.com/mootoday/sveltekit-prisma
đŁÂ SvelteKit & Prisma video course
Hold on a sec â! Josh Nussbaum created a 33-lesson video course all about the topic you are interested in - SvelteKit & Prisma.
If this is of interest to you, read my summary below and head over to Joshâs course to dive deeper.
What are you going to learn?
We are going to start with a default SvelteKit application. Once initialized, we will learn how to install and configure Prisma before we will use the PrismaClient to perform create, read, update & delete (CRUD) actions against a local SQLite database.
Things you need to know
In order to get the most out of this post, I expect you are aware of the following technologies:
The foundation
Letâs start with the basics: A SvelteKit demo app.
I recommend you first create a GitHub, GitLab or Bitbucket project and start a development environment with Gitpod. Alternatively, you can follow along on your local computer.
npm init svelte@next svelte-with-prisma When prompted, select the following options:
- âWhich Svelte app template?â
SvelteKit demo app - âUse TypeScript?â
Yes - âAdd ESLint for code linting?â
No - âAdd Prettier for code formatting?â
Yes
When complete, please follow the âNext stepsâ listed in the terminal to install dependencies and start the SvelteKit demo app.
If youâve followed along so far, you can copy & paste the following commands:
cd svelte-with-prisma
npm install
npm run dev -- --open Thatâs how quickly you get started with SvelteKit. In your browser, you notice the âTODOSâ navigation item. If you play with this list, items are persisted on svelte.dev and deleted after a while.
Next, we are going to add Prisma to persist todo items in a local SQLite database.
Add Prisma
Prisma.io states âPrisma helps app developers build faster and make fewer errors with an open source ORM for PostgreSQL, MySQL and SQLite.â
From my personal experience, this statement is certainly true. Letâs go and experience it for yourself.
Install & initialize Prisma
First things first: npm i -D prisma because, well⊠without dependencies we wonât get very far đ.
Next, we are going to initialize Prisma. For that, we use npx to execute commands.
npx prisma init â ïž This currently overwrites an existing
.gitignorefile. Keep an eye on 8496.
This creates a prisma directory at the root of the project. In it, you find the schema.prisma file.
At this point, I recommend you install the prisma.prisma VS Code extension. It adds syntax highlighting, formatting, auto-completion, jump-to-definition and linting for .prisma files.
Define the Todo model
Open the prisma/schema.prisma file and add the following model definition to the end of the file:
model Todo {
uid String @id @default(cuid())
created_at DateTime
text String
done Boolean
} Psst⊠How do we know what fields to define? Well, we take a peek at the Todo type definition in src/routes/todos/index.svelte đ.
Configure a SQLite database
Open the .env file (that file was created by the npx prisma init command earlier). In it, set the DATABASE_URL to "file:./dev.db"
We also have to open the prisma/schema.prisma file to update the datasource.db.provider to sqlite.
Check the reference docs for more details on the above two values and what other databases are supported.
Create the database and tables
Weâre making great progress! Letâs now use the Prisma CLI to create our SQLite database and create a schema based on the Todo model we defined earlier.
Itâs easy:
npx prisma db push Give that five seconds âł.
I recommend you read through the console output, I find it highly interesting. For one, it gives us a good deal of detail about whatâs going on. However, it also contains the following output which is one of the reasons Iâm mind-blown by Prisma:
â Generated Prisma Client (2.28.0) to ./node_modules/@prisma/client So much goodness! Basically, they use the Todo model to auto-generate a bunch of TypeScript definitions and Javascript code which we are going to import in just a second. In other words, the âPrisma helps app developers build faster and make fewer errorsâ sentence on the Prisma website is not just some marketing speech, it is truly genius!
Ok, Iâm done being a fanboy about it, letâs move on and thanks for your patience there with me đ .
One last thing, please add prisma/dev.db to your .gitignore file since we donât want to commit the dev database to version control.
Use the PrismaClient to interact with the database
The SvelteKit demo app nicely encapsulates all API features in the src/routes/todos/_api.ts file. To be more precise, the actual CRUD logic happens at https://api.svelte.dev/todos. We are going to modify the _api.ts file slightly to deal with CRUD right there and use the PrismaClient instead of delegating to a backend API.
Move the Todo type so we can reuse it
First and foremost, letâs move the Todo Typescript type. By default, itâs defined and used in the src/routes/todos/index.svelte file. However, with the changes weâre going to make to the API, we are also going to need that type in the src/routes/todos/_api.ts file.
- Cut the
Todotype fromsrc/routes/todos/index.svelte - Paste it below the
importstatements insrc/routes/todos/_api.ts, and prefix it withexport - Use the following import in the
src/routes/todos/index.sveltefile:import type { Todo } from "./_api";
Update the API to use Prisma
Open the src/routes/todos/_api.ts file and add the following import:
import { PrismaClient } from '@prisma/client'; Remember? Thatâs the generated code I was so excited about earlier đ.
Next, we need a new instance of the PrismaClient (add this below the import statements):
const prisma = new PrismaClient(); Moving right along, itâs time to update the api method signature to tell Typescript that the data parameter is of type Todo.
export async function api(request: Request<Locals>, resource: string, data?: Todo) { The following code:
const res = await fetch(`${base}/${resource}`, {
method: request.method,
headers: {
'content-type': 'application/json'
},
body: data && JSON.stringify(data)
}); needs to be replaced with this:
let body = {};
let status = 500;
switch (request.method.toUpperCase()) {
case 'DELETE':
await prisma.todo.delete({
where: {
uid: resource.split('/').pop()
}
});
status = 200;
break;
case 'GET':
body = await prisma.todo.findMany();
status = 200;
break;
case 'PATCH':
body = await prisma.todo.update({
data: {
done: data.done,
text: data.text
},
where: {
uid: resource.split('/').pop()
}
});
status = 200;
break;
case 'POST':
body = await prisma.todo.create({
data: {
created_at: new Date(),
done: false,
text: data.text
}
});
status = 201;
break;
} Weâre getting there đȘ. In the if statement right below the code weâve just added, remove the res.ok && since we no longer have a res variable.
Lastly, change the return statement to the following:
return {
status,
body
}; Letâs test
Start your SvelteKit demo app with npm run dev and navigate to http://localhost:3000 in your browser. If you use Gitpod, hold CTRL / CMD pressed and click on the http://localhost:3000 URL in the terminal, itâll open a new browser window with the SvelteKit demo app.
Click on the âTODOSâ navigation link and add a few todos, rename some, mark others as done.
In a new terminal, open the Prisma Studio with npx prisma studio. The studio opens in a new browser tab. Click on the Todo model and validate that the data matches what you see in the SvelteKit demo app.
Congratulations đ!
Bonus - definitely read this
Disable JavaScript in your browser and test the todo list again. This is how the web is supposed to work - without JavaScript!
We used to develop websites like that, then we spent a decade thinking itâs a great idea to move everything into JavaScript and thanks to Svelte & SvelteKit, we now once again develop web applications that work the way the web was intended to work.
JavaScriptâs purpose is to enhance the web experience, not break everything if JavaScript is disabled.
Conclusion
With a few modifications to a default SvelteKit demo app, we managed to configure Prisma to persist todo items. There is of course a lot more you can do with Prisma, and with SvelteKit for that matter. The source code at https://github.com/mootoday/sveltekit-prisma should get you a long way towards your own web app.
If you found this interesting, you may also like (wow⊠is this an e-commerce website đ?!) my current project called Webstone. Webstone is a full-stack web application boilerplate with a CLI to automate tedious tasks like adding new pages, updating the database (of course it uses Prisma đ). Itâs in early development, but do hit that star button on GitHub which helps me get motivated to spend more time on the project đ.
đ
