How an open-source Notion reverse proxy saved me from reinventing the wheel
The Moment I Almost Over-Engineered Everything
It started with a simple goal: I wanted a personal website at draphy.org. Somewhere to put my projects, write about stuff I'm learning, maybe host my resume. Nothing fancy.
My first instinct? Build a production-level CMS from scratch.
I'm a developer. I know React, Next.js, databases, all that stuff. I could totally build something custom. I was already sketching database schemas in my head. User auth, CMS backend, maybe even a headless setup with Sanity or something.
Then reality hit me.
Why am I building enterprise architecture for a site that'll get maybe 50 visitors a month? This isn't a startup. Nobody's asking for features. I don't need to scale to a million users. It's literally just me putting stuff on the internet.
I was about to spend weeks building something I could set up in minutes.
The Notion Problem (And Why Existing Solutions Didn't Work)
I already document everything in Notion anyway. Notes, project ideas, random thoughts at 2am. It's all there. And Notion has this "Publish to Web" thing that lets you share pages publicly.
Perfect, I thought. I'll just publish my Notion pages and point my custom domain to them.
Then I saw the pricing.
The Real Cost of Notion's Custom Domain
Turns out Notion buries the real cost:
- Plus Plan: $10/month (annual) or $12/month (monthly)
- Custom Domain Add-on: Additional $8/month (annual) or $10/month (monthly)
- Total: $18-22/month just to use your own domain
For a personal website that I update maybe once a week, that's $216-264/year.
And for that money? You still can't add custom CSS. Can't inject JavaScript. Can't control your SEO meta tags properly. You're stuck with whatever Notion decides looks good.
The Search for Alternatives
So I went looking for alternatives. Someone must have solved this already, right?
Fruition was everywhere in search results. Cloudflare Workers script, reverse proxy for Notion, open-source, free. Looked perfect.
It wasn't.
I checked the GitHub repo. 189 open issues. Blank screens, broken navigation, databases not rendering after some Notion update in 2023. The project's basically dead.
People were frustrated:
"Site is not loading... a white screen with an infinitely looping loading circle."
"Back button functionality is broken, causing the signup screen to appear when using browser back navigation."
"Database not rendered - after Notion update 09.2023"
The project is effectively abandoned, with dozens of people scrambling to piece together workarounds that take hours to implement. And even then, there's no guarantee they'll work.
NoteHost was another option. At least it's an actual npm package, which was nice. But last update was like 10 months ago, barely any community around it, and it was missing stuff I wanted.
I tried a few other GitHub repos too. notion-custom-domain, notion-proxy, things like that. Same story everywhere: outdated, barely documented, half-working.
The "Why Not Build It Myself?" Moment
After wasting an entire Saturday on broken Fruition configs and reading through GitHub issues that went nowhere, I just stopped.
Wait. I'm a developer. I know how reverse proxies work. Why am I fighting someone else's broken code when I could just... write my own?
So that's what I did. I called it Nooxy because all the good names were taken and I was tired.
What is Nooxy?
Nooxy is a Notion reverse proxy. TypeScript, zero dependencies, works on Cloudflare Workers or Node.js. You point it at your Notion pages, it serves them on your domain.
What's actually different about it:
Zero Dependencies
I went a bit obsessive here, but no regrets. Zero runtime dependencies means:
- Faster cold starts on edge computing platforms
- Smaller bundle size
- No security vulnerabilities from third-party packages
- No dependency conflicts or version mismatches
When you deploy to Cloudflare Workers, it's just your code. No bloat.
Works Where You Need It
Runs on:
- Cloudflare Workers (what I use)
- Node.js 18.17+
- Anything with
Request/Responsesupport really
The 5-Minute Setup
If you already have a Notion page published, you can have your custom domain working in under 5 minutes:
# 1. Install nooxy
npm install nooxy
# 2. Initialize configuration
npx nooxy init
# 3. Edit your config (add your domain and Notion page IDs)
# 4. Generate required files
npx nooxy generate
# 5. Deploy to Cloudflare Workers
That's literally it. I spent more time picking the domain name than setting this up.
The Stuff That Actually Matters
Clean URLs with Slug Mapping
Instead of ugly Notion URLs like notion.so/My-Page-abc123def456..., you get:
slugToPage: {
'/': 'YOUR_HOME_PAGE_ID',
'/about': 'YOUR_ABOUT_PAGE_ID',
'/projects': 'YOUR_PROJECTS_PAGE_ID',
'/blog': 'YOUR_BLOG_PAGE_ID',
}
Your visitors see yourdomain.com/about, not a 32-character hash.
Full Customization Control
Inject custom CSS, JavaScript, and HTML:
/* nooxy/head.css */
.notion-topbar {
display: none !important; /* Hide Notion's default navigation */
}
.notion-page-content {
max-width: 1200px;
margin: 0 auto;
}
Add custom functionality:
// nooxy/body.js
document.addEventListener('DOMContentLoaded', function() {
// Add smooth scrolling, analytics, custom interactions... whatever you need
console.log('Your Notion site, your rules.');
});
SEO That Doesn't Suck
Notion's SEO is pretty bad out of the box. With Nooxy you can actually control:
- Meta tags per page: Titles, descriptions, the works
- Open Graph stuff: So your links don't look terrible when shared
- Twitter Cards: Same deal for Twitter/X
- JSON-LD: For the SEO nerds (I am one)
pageMetadata: {
'YOUR_PAGE_ID': {
title: "'My Custom Title - Draphy',"
description: "'A description optimized for search engines',"
image: 'https://yourdomain.com/og-image.jpg',
author: 'David Raphi',
},
}
Local Development Support
Test your site locally before deployment:
// Nooxy automatically detects localhost and adjusts
// No special configuration needed
const proxy = initializeNooxy(SITE_CONFIG);
Run wrangler dev and see your changes instantly at localhost:8787.
Multi-Instance Support
Running multiple Notion sites? Nooxy supports that:
const prodProxy = initializeNooxy({
configKey: 'production',
config: productionConfig,
});
const stagingProxy = initializeNooxy({
configKey: 'staging',
config: stagingConfig,
});
Each instance gets its own cache and configuration.
Automatic Minification
The CLI automatically minifies your custom CSS, JavaScript, and HTML during the build process:
npx nooxy generate # Minifies by default
npx nooxy generate --no-minify # Skip minification if needed
How It Stacks Up (Honestly)
Look, I built this thing so I'm biased. But here's the actual comparison:
| Feature | Nooxy | Fruition | NoteHost | Notion Sites |
|---|---|---|---|---|
| Price | Free | Free | Free | $18-22/month |
| Custom Domain | Yes | Yes | Yes | Yes |
| Custom CSS/JS | Yes | Limited | Yes | No |
| SEO Control | Full | Partial | Partial | Limited |
| TypeScript | Yes | No | Yes | N/A |
| Zero Dependencies | Yes | No | No | N/A |
| Actively Maintained | Yes | No (189 issues) | Partially | Yes |
| CLI Tools | Yes | No | Yes | N/A |
| Local Dev Support | Yes | No | Partial | N/A |
| Multi-instance | Yes | No | No | N/A |
Use Nooxy If...
You'll probably like it if you:
- Don't want to pay monthly for something this simple
- Want to actually customize your site (CSS, JS, whatever)
- Care about SEO
- Like testing locally before deploying
- Are fine with Cloudflare Workers or Node.js
Skip Nooxy If...
Not gonna pretend it's for everyone:
- You hate terminals (you'll need to run a few commands)
- You want official Notion support (this is just me)
- You're not using Cloudflare or Node
- You need fancy analytics dashboards built-in
- You need visitors to see real-time edits or collaboration stuff
What About Just Paying Notion?
Fair question. Notion Sites isn't terrible if you:
- Have the budget ($18-22/month adds up though)
- Don't care about custom styling
- Just want it to work with zero effort
Nothing wrong with that. I just didn't want another monthly subscription for something I could build in a weekend.
How It's Going For Me
Been running os.draphy.org on Nooxy for a while now.
Setup: Took like 5 minutes. Most of that was finding my Notion page IDs.
Speed: It's on Cloudflare's edge network so it's fast everywhere. Haven't had complaints.
Maintenance: Basically none. I forget it's even running most of the time.
Customization: I've got my own nav, custom styles, proper SEO. Stuff that Notion just won't let you do.
Getting Started
Want to try it? Here's the quick version:
1. Install and Initialize
npm install nooxy
npx nooxy init
This creates a nooxy/ directory with all configuration files.
2. Configure Your Site
Edit nooxy/config.js:
export const SITE_CONFIG = {
domain: 'yourdomain.com',
notionDomain: 'your-workspace.notion.site',
siteName: 'Your Site Name',
slugToPage: {
'/': 'YOUR_HOME_PAGE_ID',
'/about': 'YOUR_ABOUT_PAGE_ID',
},
// These are auto-generated, just import them
customHeadCSS: HEAD_CSS_STRING,
customHeadJS: HEAD_JS_STRING,
customBodyJS: BODY_JS_STRING,
customHeader: HEADER_HTML_STRING,
};
3. Find Your Notion Page IDs
Open your Notion page → Share → Copy link. The ID is the 32-character string at the end:
notion.so/My-Page-Title-abc123def456789012345678901234
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is your page ID
4. Generate and Deploy
npx nooxy generate # Creates minified string files
# Then deploy to Cloudflare Workers
wrangler deploy
5. Point Your Domain
In Cloudflare, add a CNAME record pointing to your Worker.
Done.
Why I Built It This Way
A few things I kept in mind:
Don't overbuild. A personal site doesn't need a CMS.
Dependencies are debt. Every package you add is a future breaking change waiting to happen. I wanted something I wouldn't have to fix every time some library updated.
Make it actually usable. CLI tools, TypeScript, local dev. Not because they're trendy but because I actually wanted to use this thing.
Found a Bug? Want to Contribute?
It's open source (MIT). PRs welcome.
- Code: github.com/draphy/nooxy
- Issues: github.com/draphy/nooxy/issues
- Discussions: github.com/draphy/nooxy/discussions
Wrapping Up
I wanted a personal website. I almost spent weeks building a CMS I didn't need. Then I almost paid Notion $20/month for features I could build myself.
Instead I spent a weekend building Nooxy. Now my site runs for free, looks how I want, and I don't think about it.
If you use Notion and want a custom domain without the subscription, maybe give it a try. Five minutes, free, you own everything.
If it's useful, star it on GitHub. If it's broken, open an issue. Either way, thanks for reading.
About the author: David Raphi is a full-stack engineer who's shipped systems for US government agencies (Florida DCF, Republican Party of Florida) and led teams delivering election-critical platforms in 1-week sprints. Lives in Cloudflare's stack and has a thing for zero-dependency packages (PushForge is another one).
GitHub · Twitter/X · LinkedIn · contact@draphy.org · david@draphy.org
Top comments (0)