Skip to content

AirKyzzZ/nullpost

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


╔╗╔╦ ╦╦ ╦ ╔═╗╔═╗╔═╗╔╦╗ ║║║║ ║║ ║ ╠═╝║ ║╚═╗ ║ ╝╚╝╚═╝╩═╝╩═╝╩ ╚═╝╚═╝ ╩

Private, encrypted, self-hosted micro-blogging.
Your thoughts. Your servers. Your rules.

Live Demo · Deploy · Features

License Next.js Encryption


NullPost is a micro-blogging platform for people who want to own their words. Every post is encrypted client-side before it touches the server — your data stays yours, even on hosted infrastructure.

Built with a Watch Dogs 2 terminal aesthetic. No tracking. No algorithms. No AI. Just text.

Features

Encryption

  • AES-256-GCM encryption with PBKDF2 key derivation (600k iterations)
  • Client-side only — the server never sees your plaintext or passphrase
  • Per-post unique IVs, encryption verifier system

Blogging

  • Two post types: quick thoughts and titled longform posts (Markdown)
  • Create, edit, delete — all with real-time encrypt/decrypt
  • Tag system with color coding and feed filtering
  • Full-text search across decrypted posts (runs entirely in-browser)
  • Media uploads (images, audio, video) with encrypted filenames
  • Paginated feed with "load more"

Settings

  • Change password, change passphrase (transactional re-encryption)
  • Export all decrypted data as JSON

Design

  • Watch Dogs 2 terminal aesthetic throughout
  • Matrix rain, glitch effects, scan lines, ASCII art
  • JetBrains Mono + Inter typography pairing
  • Desktop-first, responsive

Self-hostable

  • Single-user, single-tenant by design
  • SQLite (local) or Turso (hosted) — same codebase
  • Deploy anywhere: Netlify, Vercel, Docker, VPS

Tech Stack

Layer Tech
Framework Next.js 16 (App Router, Turbopack)
Language TypeScript (strict)
Styling Tailwind CSS v4
Database SQLite via libSQL (local or Turso)
ORM Drizzle
Auth Auth.js v5 (GitHub OAuth, JWT httpOnly cookies)
Encryption Web Crypto API (AES-256-GCM, PBKDF2)
State Zustand
Animations Framer Motion

Deploy

Netlify + Turso (recommended)

  1. Create a Turso database

    Sign up at turso.tech (free tier: 500M reads, 10M writes/month), create a database, and generate a token.

  2. Push the schema

    DATABASE_URL=libsql://your-db.turso.io DATABASE_AUTH_TOKEN=your-token npx drizzle-kit push
  3. Deploy to Netlify

    Connect your repo, then set these environment variables:

    DATABASE_URL=libsql://your-db.turso.io
    DATABASE_AUTH_TOKEN=your-token
    

    Netlify will auto-detect Next.js and build with @netlify/plugin-nextjs.

  4. Visit /setup to create your account.

Docker (self-hosted)

# Using docker-compose (recommended)
git clone https://github.com/AirKyzzZ/nullpost.git
cd nullpost
docker compose up -d

Or run directly:

docker run -d \
  -p 3000:3000 \
  -v nullpost-data:/app/data \
  -e DATABASE_URL=file:./data/nullpost.db \
  ghcr.io/airkyzzz/nullpost:latest

Data (SQLite + uploaded media) persists in the nullpost-data volume. Migrations run automatically on startup.

Manual

git clone https://github.com/AirKyzzZ/nullpost.git
cd nullpost
npm install
npx drizzle-kit push
npm run build
npm start

Development

npm install
npm run dev -- -p 3002

The app runs at http://localhost:3002. On first visit, go to /setup to create your account.

Environment Variables

Variable Required Default Description
DATABASE_URL No file:./data/nullpost.db libSQL connection string
DATABASE_AUTH_TOKEN For Turso Turso authentication token

Schema Changes

# Edit src/lib/db/schema.ts, then:
npx drizzle-kit push

Architecture

Browser                          Server                    Database
┌─────────────┐                ┌──────────────┐          ┌─────────┐
│ Plaintext   │  encrypt()     │ Encrypted    │  store   │ SQLite  │
│ post/title  │ ──────────────>│ ciphertext   │ ────────>│ /Turso  │
│             │  AES-256-GCM   │ + IV         │          │         │
│ Decrypted   │  decrypt()     │ Encrypted    │  fetch   │         │
│ content     │ <──────────────│ ciphertext   │ <────────│         │
└─────────────┘                └──────────────┘          └─────────┘

The server is a storage relay. It never sees plaintext content,
titles, or your passphrase. Encryption keys exist only in browser memory.

Project Structure

src/
├── app/
│   ├── api/posts/          # Post CRUD endpoints
│   ├── api/tags/           # Tag CRUD endpoints
│   ├── api/media/          # Media upload, serve, delete endpoints
│   ├── api/auth/           # Auth endpoints (setup, login, logout, password, passphrase)
│   ├── app/feed/           # Feed page (list + filter posts)
│   ├── app/post/           # New, view, edit post pages
│   ├── app/media/          # Media gallery
│   ├── app/tags/           # Tag management
│   ├── app/search/         # Client-side encrypted search
│   ├── app/settings/       # Settings (password, passphrase, export)
│   ├── login/              # Login page
│   └── setup/              # First-time setup wizard
├── components/
│   ├── app/                # App components (editor, cards, sidebar, header, media)
│   ├── auth/               # Auth components (login form, setup wizard, passphrase gate)
│   ├── landing/            # Landing page sections
│   └── ui/                 # Primitives (button, input, toast, tag badge, etc.)
├── lib/
│   ├── auth/               # Password hashing, session management
│   ├── crypto/             # AES-256-GCM encrypt/decrypt, key derivation, key store
│   └── db/                 # Database connection, schema, migrations
├── instrumentation.ts      # Auto-runs migrations on startup
└── middleware.ts            # Route protection

Security Model

  • Passphrase → PBKDF2 (600k iterations, SHA-256) → CryptoKey
  • CryptoKey + random IV → AES-256-GCM → ciphertext
  • Passphrase never leaves the browser
  • Server stores only ciphertext, IVs, and a verifier blob
  • Session auth via Auth.js v5 (GitHub OAuth, JWT httpOnly cookies)
  • Single-user design eliminates multi-tenant attack surface

Threat model: protects against server compromise and database leaks. Does not protect against a compromised browser or keylogger on the client device.

Documentation

  • Architecture technique — Stack, flux d'authentification, chiffrement, schéma DB, API, sécurité, tests, CI/CD

License

AGPL-3.0 — free to use, modify, and self-host. Modifications to the source must be shared under the same license.


Built by Maxime Mansiet

About

A private, encrypted, self-hosted micro-blogging platform. Watch Dogs terminal aesthetic. Open source.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages