Remix + EdgeDB + Netlify 🕺
Deployed Site: khiphop-stack.netlify.app
Heavily Inspired By:
- K-Pop Stack
- This stack also uses Netlify :), hence another korean music genre
- Remix Chop Suey Stack
- Used a lot of the edge db / clerk setup
Learn more about Remix Stacks.
npx create-remix --template acerom/khiphop-stack
Click this button to create a new Github repo, new Netlify project and deploy this stack to a CDN.
- Netlify Deployment to the Edge + deploy previews and CI/CD
- Clerk For simple user authentication
- EdgeDB Next generation graph-relational database with access policies for object level security
- Tailwind For styling and DaisyUI for quick UI prototyping
- Cypress End-to-end testing
- Prettier Code formatting
- ESLint Linting
- TypeScript
- Clsx For conditional styling
- Headless UI Essential component primitives used for modals, popovers etc.
- Zod + Remix Params Helper Server-sided form validation
- Conform Great client sided form validation package by edmundhung using the Constraint Validation API
- Tiny Invariant Handy tool for validating the existence of variables
- Remix Flat Route Flat file directory structure
Don't like what's in this stack? Feel free to create an issue, fork this repo, or clone and make it your own!
- Netlify has a lot of great features for CICD, DX and you also can opt in for usage on the Edge
- Supabase/Prisma is great, but I think edge db does a slightly better job with migrations, and overall has a smoother developer experience. Since the release of EdgeDB 2.0, it has been easier to visualize the db layer and create queries using the
edgedb ui
command - I want to share my personal codebase preferences :)
This repo is still in active development! To get an idea of what I'm working on, feel free to look at my TODO
khiphopstack-demo_vb0ptv.mov
-
Install all dependencies & the Netlify CLI:
npm install npm install netlify-cli -g
-
Create or connect to your Netlify project by running through the Netlify
init
script:netlify init
For local development, first make sure you have edgedb installed (follow the quickstart)
- Initialize your project
edgedb project init
- Now we need to create and apply the migrations to our new database
edgedb migration create
edgedb migration apply
- Generate the edgedb types required for your project. All your types will now be located in
./app/db/edgeql
Note that the generated types are not in the .gitignore since netlify uses them to build your app
npm run generate:eql
Make sure you installed all the packages
npm install
The Remix dev server starts your app in development mode, rebuilding assets on file changes. To start the Remix dev server:
npm run dev
The Netlify CLI builds a production version of your Remix App Server and splits it into Netlify Functions that run locally. This includes any custom Netlify functions you've developed. The Netlify CLI runs all of this in its development mode.
It will pull in all the environment variables of your Netlify project. You can learn more about this project's EdgeDB environment variables in the environment variables section.
To start the Netlify development environment:
netlify dev
With Netlify Dev you can also:
- test functions
- test redirects
- share a live session via url with
netlify dev --live
- and more :)
Note: When running the Netlify CLI, file changes will rebuild assets, but you will not see the changes to the page you are on unless you do a browser refresh of the page. Due to how the Netlify CLI builds the Remix App Server, it does not support hot module reloading.
module default {
global current_user -> str;
type User {
required property clerk_id -> str { constraint exclusive };
required property alias -> str { constraint exclusive };
required property is_onboarded -> bool { default := false };
}
type Note {
required link author -> User;
required property name -> str;
property description -> str;
access policy insert_notes allow insert;
access policy own_notes allow select, delete, update using (
.author ?= (select User filter .clerk_id = global current_user)
);
}
}
- When creating a new User, we only store their
clerk_id
and username - We have an
is_onboarded
field that we set true once user passes onboarding. If onboarded a signed in user will always redirect to the app and vice versa. - We define object-level security using access policies such that users can only query, delete, and update their own notes based on their
clerk_id
This is a pretty simple CRUD note-taking app, but it's a good example of how you can build a full stack app with Remix, EdgeDB, and Netlify
- Clerk Routes
- Sign in ./apps/routes/_auth
- Onboarding ./apps/routes/onboarding
- After a user creates an account with clerk, we store the clerk_id and require the username/alias from the user before having access to our main app
- CRUD operations in edgedb ./app/models
- App Home (Placeholder dashboard home route incase the app gets more complex with more models/routes)
- ./app/routes/app.index.tsx
- Right now this route will have one button to lead to the notes page
- View Notes (With Note Search and Remove Note Option) ./app/routes/app.notes.index.tsx
- View Note ./app/routes/app.note.$noteId.tsx
- New Note ./app/routes/app.notes.new.tsx
- Edit Note ./app/routes/app.note.edit.$noteId.tsx
To set environment variables, you can use the Netlify UI:
Or you can add your environment variables to an .env
file (like shown in the sample .env.sample
) which will not be committed publicly because it is added to the .gitignore
file. Or you can add it to your Netlify project environment variables (Site settings/Build & deploy/Environment) as shown in the Development section so that they can be easily shared with teammates.
You will need these 2 environment variables to connect to your EdgeDB fly.io instance
Please refer to Connecting Netlify Deployment to a Fly Instance to learn how to get these variables
EDGEDB_DSN
:- This is your main database URL link for your remote deployment. For local development you will just need to setup an edgedb instance offline
EDGEDB_TLS_CA
:- This is the TLS certificate key used to connect to your fly.io instance. Documentation
- You can grab this value with the following command
flyctl ssh console -a $EDB_APP -C "edgedb-show-secrets.sh --format=shell EDGEDB_SERVER_TLS_CERT"
For some reason, setting environment variables in the Netlify UI does NOT WORK for new lines (\n). To circumvent this, define your
EDGEDB_TLS_CA
variable inside yournetlify.toml
file or use a service like Doppler
This stack has the Netlify configuration file (netlify.toml) that contains all the information needed to deploy your project to Netlify's edge nodes.
Want to deploy immediately? Click this button
Clicking this button will start the setup for a new project and deployment.
Clone this repo with the git clone
command. Then install the Netlify CLI tool and run netlify init
.
git clone https://github.com/netlify-templates/kpop-stack
npm install netlify-cli -g # to install the Netlify CLI tool globally
netlify init # initialize a new Netlify project & deploy
- Deploy an EdgeDB instance to fly.io by following the setup instructions here: Deploying EdgeDB to Fly.io
- Save your current fly config
flyctl config save -a $EDB_APP
- Make sure your services section looks like this:
[[services]]
http_checks = []
internal_port = 8080
processes = ["app"]
protocol = "tcp"
script_checks = []
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"
[[services.ports]]
port = 5656
[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"
- Then run
flyctl deploy --image=edgedb/edgedb --remote-only --app $EDB_APP
- Your public EdgeDB DSN will be
edgedb://edgedb:$PASSWORD@$EDB_APP.fly.dev:5656
You will also need to set EDGEDB_CLIENT_TLS_SECURITY=insecure
, but the secure way is to fetch the EdgeDB TLS certificate and specify it as EDGEDB_TLS_CA
on Netlify. To grab the cert:
flyctl ssh console -a $EDB_APP -C "edgedb-show-secrets.sh --format=raw EDGEDB_SERVER_TLS_CERT"
Using the 'Deploy to Netlify' button or the init
process will also set up continuous deployment for your project so that a new build will be triggered & deployed when you push code to the repo (you can change this from your project dashboard: Site Settings/Build & deploy/Continuous Deployment).
You can also use netlify deploy
or netlify deploy --prod
to manually deploy then netlify open
to open your project dashboard.
💡 If you don't use
--prod
on the deploy command you will deploy a preview of your application with a link to share with teammates to see the site deployed without deploying to production
This project uses Vite for unit tests
We have set up the basic configuration files for Cypress End-to-End tests in this project. You'll find those in the cypress
directory. As you make changes, add to an existing file or create a new file in the cypress/integrations
directory to test your changes.
We use @testing-library/cypress
for selecting elements on the page semantically.
To run these tests in development, run npm run e2e-test
which will start the dev server for the app as well as the Cypress client.
To other example of Cypress tests specifically on Remix stacks, check out the cypress
directory in the Remix Grunge Stack example.
This project uses TypeScript. It's recommended to get TypeScript set up for your editor to get a really great in-editor experience with type checking and auto-complete. To run type checking across the whole project, run npm run typecheck
.
This project uses ESLint for linting. That is configured in .eslintrc.js
.
We use Prettier for auto-formatting in this project. It's recommended to install an editor plugin (like the VSCode Prettier plugin) to get auto-formatting on save. There's also a npm run format
script you can run to format all files in the project.