惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
C
Cybersecurity and Infrastructure Security Agency CISA
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
Hacker News: Ask HN
Hacker News: Ask HN
L
Lohrmann on Cybersecurity
PCI Perspectives
PCI Perspectives
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MyScale Blog
MyScale Blog
月光博客
月光博客
W
WeLiveSecurity
T
Threat Research - Cisco Blogs
Martin Fowler
Martin Fowler
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
The GitHub Blog
The GitHub Blog
Webroot Blog
Webroot Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
TaoSecurity Blog
TaoSecurity Blog
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
F
Full Disclosure
U
Unit 42
Jina AI
Jina AI
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
大猫的无限游戏
大猫的无限游戏
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
T
Troy Hunt's Blog
腾讯CDC
T
Threatpost
H
Hacker News: Front Page
P
Palo Alto Networks Blog
博客园 - 聂微东
Last Week in AI
Last Week in AI
有赞技术团队
有赞技术团队
Help Net Security
Help Net Security
L
LINUX DO - 热门话题
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Spread Privacy
Spread Privacy

Clerk Blog

Going to production with Clerk Deploy Clerk Init: The fastest way to start a new project Introducing Clerk CLI Middleware-based route protection bypass Postmortem: Clerk System Outage (March 10, 2026) Clerk for the AI era Add API Key support to your SaaS in minutes Postmortem: Clerk System Outage (February 19, 2026) Using Clerk in a React Native app Postmortem: DNS Provider Outage (February 10, 2026) How do I implement passkeys in Next.js? Clerk ranked #4 fastest-growing software vendor on Ramp’s December 2025 list How do I handle JWT verification in Next.js? Committing to Agent Identity: Clerk raises $50m Series C from Menlo and Anthropic’s Anthology Fund What is the best way to handle authentication in Next.js App Router? Postmortem: Database Incident (September 14–18, 2025) How do I add authentication to a Next.js app? Introducing Free Trials in Clerk Billing Postmortem: August 28, 2025 - elevated API latency and errors Introducing Mosaic: Bring Your Brand to Every Authentication Flow Multi-tenant authentication: What you need to know (and how Clerk helps) What are the risks and challenges of multi-tenancy? Resilience in Practice: Regional Failover at Clerk Build a Cross-Platform B2B App with Clerk, Expo, and Supabase Highlights from the MiduDev/Clerk Hackathon Add multi-tenancy to an app built with Clerk, Lovable, and Supabase How to build an AI coding rules app with Clerk, Lovable, and Supabase How to Build Multi-Tenant Authentication with Clerk Choosing the right SaaS architecture: Multi-Tenant vs. Single-Tenant Postmortem: June 26, 2025 service outage How to Design a Multi-Tenant SaaS Architecture What is multi-tenancy and why it matters for B2B SaaS How OAuth Works Synchronize user data from Clerk to Supabase Add subscriptions to your SaaS with Clerk Billing Getting started with Clerk Billing Multi-tenant analytics with Tinybird and Clerk How Huntr Migrated 250K Users to Clerk: A Scalable Auth Solution for Startups How to take Clerk to Production How to take your Clerk application to production A practical guide to testing Clerk Next.js applications Implementing multi-tenancy into a Supabase app with Clerk How Clerk integrates with a Next.js application using Supabase How Clerk integrates with Supabase Build a blog with tRPC, Prisma, Next.js and Clerk How to enrich PostHog events with Clerk user data How to build a secure project management platform with Next.js, Clerk, and Neon Validate your SaaS idea while building an audience Postmortem: February 6, 2025 service outage Implement Role-Based Access Control in Next.js 15 Build a Next.js sign-up form with React Hook Form Build a Next.js login page template How to implement Google authentication in Next.js 15 What is middleware in Next.js? How to customize Next.js metadata How to set environment variables in Node.js Building a React Login Page Template How to implement per-user OAuth scopes with Clerk Using Clerk SSO to access Google Calendar and other service data Streamline enterprise customer onboarding with SAML and Clerk Clerk launches EASIE SSO and eliminates SSO fees How to secure Liveblocks Rooms with Clerk in Next.js Securing Node.js Express APIs with Clerk and React Combining the benefits of session tokens and JWTs Build a task manager with Next.js, Supabase, and Clerk Comparing Clerk Webhooks vs Backend API Automate Neon schema changes with Drizzle and GitHub Actions A guide to reading authenticated user data from Clerk Role based access control with Clerk Organizations Mitigating OAuth’s recently discovered Open Response Type vulnerability Per-user B2B monetization with Stripe and Clerk Organizations Build a team-based task manager with Next.js, Neon, and Clerk Building a Hybrid Sign-Up/Subscribe Form with Stripe Elements Welcoming Colin from Zod as our inaugural Open Source Fellow Build a modern authenticated chat application with Next.js, Ably, and Clerk Build a waitlist with Clerk user metadata How to use Clerk with PostHog Identify in Next.js How to secure API Gateway using JWT and Lambda Authorizers with Clerk What are passkeys and how do they work? Comparing Authentication in React.js vs. Next.js How to Add an Onboarding Flow for your Application with Clerk Create Your Own Custom User Menu with Radix - Part 2 Introducing Webhook Workflows with Inngest & Svix Clerk raises $30M Series B from CRV and Stripe Clerk in 2023: A Year in Review Build a Movie Emoji Quiz App with Remix, Fauna, and Clerk Ultimate Guide to Magic Link Authentication Create Your Own Custom User Menu with Radix Introducing has(), protect(), and <Protect> Updated Pricing: 10,000 MAUs Free, and a new “Pro Plan” Next.js Authentication with Clerk: Streamlined SSR Handling Clerk Webhooks: Data Sync with Convex Exploring Clerk Metadata with Stripe Webhooks The Ultimate Guide to Next.js Authentication Empower Your Support Team With User Impersonation Clerk Webhooks: Getting Started A Complete Guide to Session Management in Next.js The Advanced Guide to Passwordless Authentication in Next.js How We Roll – Chapter 10: Roundup How We Roll – Chapter 9: Infrastructure
Build a to-do app with Clerk and Hasura— and no backend code
Nacho Iacovino · 2021-05-28 · via Clerk Blog

Introduction

While traditional applications require both frontend and backend developers, new technologies like Clerk and Hasura are making it possible to build robust backends without writing backend code.

In this tutorial, we'll leverage these new technologies to build a simple to-do list application without writing any backend code. The primary tools we'll use are:

Before we get started, you can see the final result here:

Let's begin!

Create a Hasura project

Start by signing up for Hasura Cloud.

If you already have a Hasura Cloud account, you will need to manually create a New Project. If this is your first time, a new project will automatically be created for you.

After your project initializes, you will see something like this (with a different name), go ahead and click the cog wheel to go to the project settings:

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

From here, you will need our project's GraphQL API URL. Please copy it, you will need it in a second:

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

Deploy the starter project

We prepared a starter project for this tutorial, the easiest way to get started is with the following "Deploy" button. The button will prompt you through cloning the repo, initializing Clerk, and deploying the app live on Vercel. The starter project uses Next.js, Tailwind CSS and Clerk. It's already setup with some styles using Next.js and Tailwind CSS but you don't have to be proficient in either of these to follow the tutorial.

Deploy with Vercel

This button will first prompt you to create a Vercel account if you do not have one. When signing up, Vercel may ask you to grant access to all of your repositories or just selected ones - feel free to choose either option.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

The Next step will prompt you to integrate Clerk into your project, click Install.

If you do not have a Clerk account already, you will be asked to create one now.

Next, you will be asked to select an application name and a brand color. Then, click "Create application":

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

After the window closes, click Continue and you will be prompted to pick a Git provider. In this tutorial, we will use GitHub:

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

This is where you will use Hasura Cloud's GraphQL API URL you copied earlier. Add it below and click Deploy.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

While you wait for Vercel to deploy our project, you can move to GitHub, where Vercel has created a new repository on your behalf. Go ahead and clone it locally.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

To clone, go to your desired folder, open a terminal and paste:

Then, go inside the project folder and run:

This will install the necessary dependencies.

After this, go ahead and launch your project:

If you haven’t previously used Vercel on your computer, you will be asked to sign in when you launch the project.

You will be prompted to set up link this local project with the Vercel project. Respond **Y** to each prompt.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

Then, you will see your project running on http://localhost:3000.

File structure

Activate Hasura integration

Hasura is one of the integrations that Clerk offers, with many more coming the future. To use it, you need to enable it. Go to your Clerk dashboard, click on your application -> Development -> Integrations and activate Hasura.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

Before leaving the dashboard, go to Home and copy your Frontend API, you'll need to to create the link between Clerk and Hasura.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

With your project already running, it's time to go back to Hasura and start setting up the database.

Set up Hasura Cloud

Go back to Hasura, click the cog wheel, click "Env vars" and then "New Env Var".

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

Pick HASURA_GRAPHQL_JWT_SECRET from the list and then add this, replacing %FRONTEND_API% with the Frontend API you copied from Clerk.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

Click "Add" and then, click "Launch Console".

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

This will bring us to GraphiQL. GraphiQL is the GraphQL integrated development environment (IDE). It's a powerful tool you can use to interact with the API.

After GraphiQL opens, the first thing you need to do is to create a table. Start by clicking Data on the top navbar:

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

For this tutorial, we recommend creating a Heroku database for free:

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

If you don't have a Heroku account, now is the time to create one.

Follow the steps and the database will automatically be created and linked for you.

After the database is created, click "Public" and then "Create Table"

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

Fill the table like this and "Add Table".

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

This not only creates our table, but also triggers Hasura to create a GraphQL backend.

After creating the table, the next step is to restrict who can access the data. By default, Hasura is configured for all fields to be public. You need to set permissions and fix that.

Set table permissions

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

You need to create a new role called "user" and edit each of the four possible permissions they have. If you are familiar with CRUD (Create, Read, Update, Delete), this is basically the same thing.

Insert (Create)

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

For Insert permissions, choose that the user can only set the title of a to-do when a new one is created. There others all have default values:

  • id is autogenerated (set during table creation)
  • completed starts as false
  • created_at is autogenerated to now() (set during table creation)
  • user_id is set to the requesting user's ID

Since the user_id is dependent on the particular request, it must be configured as a "Column preset."Set it to X-Hasura-User-Id from the "session variable."

When you use Clerk's Hasura integration, X-Hasura-User-ID is automatically set in the session variable that gets sent to Hasura. The code to retrieve the session variable and send it to Hasura is in lib/apolloClient.js.

Select (Read)

For Select permissions, you want to configure Hasura so users can only read their own to-dos. You can verify this by "checking" if the to-do's user_id is the same as the X-Hasura-User-Id you receive from the session variable.

If the user ID's match, you can grant read permissions to every column. The exact configuration required is below:

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

Update

For Update permissions, you want to include the same "check" as Select, to ensure that a user can only update their own to-dos.

However, if the check is valid, you don't want the user to have permission to update every column. Instead, only grant permission to update the completed column.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

Delete

For Delete permissions, you want to include the same "check" as Select, to ensure that a user can only delete their own to-dos.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

That's all of the permissions we need to set! Now, let's work on the frontend.

Connect Hasura to the Frontend

Go to http://localhost:3000 and create an account on your app. Then, click "Start saving your todos" and you will see this:

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

These is sample data and is still static. In the next steps of the tutorial, we will connect this list to Hasura and your database, so users can create and manage their own to-dos.

Create a to-do

The first step is giving users the ability to create a to-do. We will do this from components/AddTodo.js.

If you look at the onSubmit function, you will see that nothing will currently happen when the user clicks add. You must create a GraphQL "mutation" to update the database when add is clicked.

Replace the top of your file (everything above the return statement) with this code:

This mutation accepts a title and passes it to the insert_todos_one method that Hasura has created for us.

Now, let's go back to our frontend and try adding a todo.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

You'll see notice that nothing happens on the frontend, and that's expected because we're still reading static to-dos. But, let's check the database to see if the mutation succeeded. Go back to the Hasura Cloud Console, copy and paste the following query and click the play button:

You should see your todo was created successfully:

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

Fetch to-dos

Now, we will update the frontend to read the user's to-dos from Hasura. You can do this from components/TodoList.js.

The file starts by showing static data. Update the component to instead run a GraphQL "query":

First, we created a query that gets all to-dos (remember, the user can only see the ones attached to their own user_id). We set the query to return id, title, and completed. We order the to-dos by created_at descending, so the newest are first in the list.

useQuery returns an object so you can render different things depending on if the data is loading, if there's an error, or if the data has been retrieved.

We've configured an early return while the data is loading or if there's an error, then render the list if that is available. After saving, you should see something like this:

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

Let's try adding a new todo.

Build A To Do App With Clerk And Hasura And No Backend Code guide illustration

You should see that the form clears after clicking "Add", but the list below doesn't automatically update. However, if you manually refresh the page, you will see new to-do.

That's not the best experience and we will fix this later by implementing a cache, so your can keep your database and your frontend in sync.

Before that, let's implement toggle and delete mutations.

Delete Todo

Open components/SingleTodo.js, which is the component the renders for each individual to-do.

Update the code to add a delete mutation when the delete button is clicked:

Now, try deleting a todo. It works, but you get same experience as inserting. You need to refresh the page to see it.

We will fix this shortly, but first let's add toggle functionality.

Toggle Todo

Still inside components/SingleTodo.js, now you can add a new toggle mutation. Here is the updated component with both delete and toggle functionality:

Now, every CRUD operation works. But you need still need to refresh the page to see changes. Let's fix that.

Notice we are importing GET_TODOS, we'll need it for the next step.

Using Apollo Cache

The GraphQL library this tutorial uses, Apollo, implements a dynamic, local cache. Instead of reloading the full list of updates after each mutation, you can run the mutations against your local cache. Then, the to-do list on your frontend will automatically be updated.

One great feature of this cache is called the optimisticResponse. With this, you can assume that your GraphQL mutations will succeed and reflect the change in your frontend right away, instead of waiting for the success message from Hasura. The optimisticResponse is preferred for your to-do app since you're not anticipating any errors, and it results in a faster-feeling user experience.

To use the cache, you need to add the cache and optimisticResponse parameters to your mutation functions.

In your deleteTodo function:

In your toggleTodo function:

Finally, we must leverage the cache in components/AddTodo.js:

At the top of the file, add:

And update your onSubmit as follows:

Final thoughts

That's it! You now have a complete to-do list using Clerk, Hasura, and Next.js - and you didn't write any backend code. It's powerful, easy to configure, and easy to scale.

If you have enjoyed this tutorial or have questions or concerns, please check our support page. If you prefer Twitter, feel free to contact me (@nachoiacovino) or Clerk (@clerk) directly.