danielwirtz.com: a Next.js portfolio that keeps its content in Airtable
Personal website build with Chakra UI, NextJS and Airtable ✨
At a glance
- What is it?
- The wirtzdan/website repository is a personal site and portfolio built with Next.js, Chakra UI and Airtable, where Airtable acts as a simple backend for the blog, books and tools pages. It is worth reading for the wiring rather than for a reusable framework: a mixed Airtable and Notion data layer, an optional analytics and rate limiting setup, and a licence the author keeps deliberately restrictive.
- Who is it for?
- Adopt this code if you want a worked example of a small portfolio where content lives in a hosted table rather than in the repository, and you are comfortable wiring Airtable and Notion clients into a Next.js app. Do not adopt it as a starter template without reading license.md, because the licence is a custom one that GitHub cannot classify and the author asks readers to check it before reusing the code.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Airtable is the backend behind the blog, books and tools pages
wirtzdan/website is the source of danielwirtz.com, a personal website and portfolio. The project describes itself as built with Next.js as the React framework, Chakra UI as the component library and Airtable as a simple backend, and the readme is clear about where the backend comes into play: the blog, books and tools pages.
That is the central design choice, and it is a small one with wide consequences. Content is not stored as MDX files in the repository. It sits in tables, and the site fetches it. The author points at a write-up on the site itself explaining how Airtable is used as a backend, which is the piece to read if you want the reasoning rather than the code.
The page list the author considers worth looking at is short and specific: the blog, the books page and the tools page. The rest of the site is portfolio furniture.
The stack underneath is modern Next.js with the App Router, given the top level app/ directory alongside components/, layouts/, lib/, data/ and types/. The component library is Chakra UI 3, with Radix colours and Framer Motion in the dependency list, and there is MDX support through @next/mdx, so long-form content can also come from the repository itself. The language is TypeScript, with a theme.ts at the root and a tsconfig.json.
Four terminal commands, then a .env.local file
Getting the site running locally is the part the readme documents most concretely, and it is four commands:
$ git clone https://github.com/wirtzdan/website danielwirtz.com
$ cd danielwirtz.com
$ yarn
$ yarn devThe clone target name matches the directory the site is built in, and the last command starts the development server. Behind that shorthand is a Next.js 16 application with the usual scripts, and they are worth reading in the package manifest:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",There is also an inspect script that runs the development server with the Node inspector flag on port 5000, a typecheck script running tsc with no emit, and a prepare hook that runs vp config, which belongs to the vite-plus tool in the dev dependencies.
The second half of the setup is configuration. The readme says to add environment variables if you want to play with the Airtable and Raindrop integrations, and to create a .env.local file modelled on .env.example. The example file lists the keys the site expects:
AIRTABLE_API_KEY=
AIRTABLE_BASE_ID=
RAINDROP_ACCESS_TOKEN=
BUTTONDOWN_API_KEY=The Node engine requirement is 20.9.0 or newer, which is stated in the package manifest rather than in the readme.
The lockfile and the setup notes disagree about the package manager
Here is a detail that will cost a newcomer ten minutes if nobody points it out. The readme tells you to run yarn and yarn dev. The repository also contains pnpm-lock.yaml and a .yarnrc.yml file, and the dev dependency is vite-plus rather than anything from the yarn toolchain. So the tree carries evidence of both package managers, and the notes describe only one of them.
Neither choice is wrong on its own. What it means in practice is that the clone will not behave identically depending on which installer you reach for, and that a stale lockfile can leave you with a dependency tree nobody has tested. The typecheck script exists as a way to find out whether the tree you ended up with is sane, and the repository also carries a .prettierignore, a .cursor/ directory and a .vscode/ directory, so the author is working in a fairly configured editor setup.
The entry point is index.js territory, but the real entry point is next.config.js, which is where a Next.js project configures MDX, image handling and rewrites. next-env.d.ts and the types/ directory hold the TypeScript types, and patches/ suggests the author carries patches for dependencies that do not behave as published.
Notion, Raindrop, Buttondown and a Redis rate limit sit behind the same app
The dependency list is longer than a portfolio usually needs, and it shows the real shape of the site. Airtable is there for content, and so is Notion, with @notionhq/client, notion-client, notion-compat, notion-utils and react-notion-x, plus @mdx-js/loader and @mdx-js/react for rendering Markdown and MDX. The environment file carries a Notion token, a flag named USE_OFFICIAL_NOTION_API and four database identifiers for blog pages, books, photos and the blog database, so the site can read from either source depending on configuration.
Raindrop appears as a bookmarking service with its own access token, and Buttondown appears as a newsletter service with an API key. Newsletter subscription and the contact form both write to endpoints under /api, and those endpoints are the ones the environment file mentions in a comment about distributed rate limiting:
# Distributed rate limit for POST /api/addSubscriber and POST /api/sendSuggestion.
# Create a Redis database at https://upstash.com and paste the REST URL and token.
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=The comment also says what happens locally when those two values are empty: each serverless instance falls back to an in-memory limit. That is worth reading carefully before deploying, because an in-memory fallback means the limit is per instance rather than shared.
The rest of the stack is ordinary front-end work: SWR for data fetching, next-themes for colour schemes, react-hook-form for forms, react-microsoft-clarity for analytics, next-plausible for privacy oriented analytics, Prism for syntax highlighting and react-player for media.
A custom licence that GitHub cannot classify
The licence is the part of this repository that deserves the most attention before you copy anything from it.
GitHub reports the licence as a custom one that it cannot classify, and the readme does not summarise it. Instead it points at License.md in the repository and tells you to read it before using the code in your own site. The top-level listing does contain a license.md file, so the document is there even though no standard grant is named.
Why it is not MIT, Apache or GPL is easy to guess and should not be guessed about. A personal portfolio whose content, images and design are the author's own work is a normal place to keep rights reserved, and the fact that GitHub cannot map the file onto a known licence means it is not one of the standard grants. That makes the reuse terms specific, and it makes the file the only authority.
This is a licensing note rather than legal advice. The practical point for an engineer is narrow: the code is visible, the terms are not the permissive defaults that a normal open source repository would give you, and a two minute read of license.md decides whether you can build on it.
A site that is pushed to constantly and never released
The maintenance picture is that of an actively worked personal site. The last push was on 2026-10-20 and the repository is not archived, yet there are no GitHub releases at all, which fits a project whose artefacts are deployed rather than published.
Several details point at a site that is maintained rather than archived. The homepage is the live site itself, and the author asks readers to open the blog, books and tools pages. Feedback goes to Twitter. The repository includes an AGENTS.md file at the top level, which is the convention for instructions aimed at coding agents working in the repository, and a scripts/ directory alongside the app code.
The deployment target is visible in the topic tags, which list nextjs, vercel, chakra-ui, airtable and framer-motion. The dev server command in the readme is yarn dev, and the manifest adds next start for the production server, so the production path is a standard Next.js build.
What the repository does not contain is as telling as what it does. There is no test directory, no CI workflow description in the readme, and no database schema, because the database is somebody else's table. The result is a codebase that is easy to read and easy to borrow from, and correspondingly hard to evaluate as a production system, since the parts that carry the data are outside the repository.
Editorial conclusion
Adopt this code if you want a worked example of a small portfolio where content lives in a hosted table rather than in the repository, and you are comfortable wiring Airtable and Notion clients into a Next.js app. Do not adopt it as a starter template without reading license.md, because the licence is a custom one that GitHub cannot classify and the author asks readers to check it before reusing the code. Verify first which package manager your checkout expects, since the setup notes say yarn while the repository carries a pnpm lockfile and a yarnrc file, and that the Airtable keys in .env.local are present before the blog, books and tools pages will have anything to render.
Frequently asked questions
How do I run the wirtzdan/website project locally?
Clone the repository into a danielwirtz.com directory, change into it, and run yarn followed by yarn dev. You also need a .env.local file modelled on .env.example if you want to work with the Airtable and Raindrop integrations.
What backend does the danielwirtz.com portfolio use?
Airtable is used as a simple backend, and it comes into play on the blog, books and tools pages. The dependency list also includes Notion clients, with a Notion token and four database identifiers in the example environment file.
Can I reuse this code in my own website?
Check license.md in the repository first. GitHub classifies the licence as a custom one it cannot map to a standard grant, and the readme asks readers to read that file before using the code in their own site.
Which environment variables does the site need?
The example file lists AIRTABLE_API_KEY, AIRTABLE_BASE_ID, RAINDROP_ACCESS_TOKEN, BUTTONDOWN_API_KEY, Notion credentials and database identifiers, and Upstash Redis URL and token values used for distributed rate limiting on the subscriber and suggestion endpoints.
What happens to rate limiting when the Redis values are empty?
The comment in the example environment file says to leave them empty locally, in which case each serverless instance uses an in-memory fallback, so the limit is per instance rather than shared.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/wirtzdan-website)Was this useful?