Snippets Library is a full-stack code snippet manager built with Next.js, TypeScript and Drizzle ORM. It provides authenticated snippet storage, syntax highlighting, instant search, public sharing, bookmarking, likes and view tracking.
This README summarizes the current codebase, how to run it locally, the main API surface and important implementation details discovered in the repository.
- Save, edit and delete code snippets.
- Automatic/assisted language detection (highlight.js on the server and a custom detector in the client libs).
- Syntax highlighting via Shiki with a cached highlighting service.
- Public share links (secure random share IDs) with view counting, like/unlike and copy-as-new-snippet.
- Bookmarks per-user.
- GitHub OAuth sign-in using NextAuth and a Drizzle adapter.
- Settings persisted per user including code theme and preferences.
- Next.js 15 (App Router)
- React 19 + TypeScript
- Drizzle ORM (Postgres)
- NextAuth (GitHub provider) with @auth/drizzle-adapter
- Shiki for server-side/high-quality code highlighting
- highlight.js for quick language detection endpoint
- Tailwind CSS (utility classes used in components)
The most relevant npm scripts are defined in package.json
:
npm run dev
β formats with Prettier and runs Next.js in dev mode (port 3001 by default)npm run build
β builds the Next.js appnpm run start
β runs the built Next.js app (port 3001)npm run lint
β runs Next.js ESLintnpm run db:generate
β drizzle-kit generatenpm run db:migrate
β drizzle-kit migrate and pushnpm run db:studio
β drizzle-kit studionpm run migrate
β runs generate then migrate
Use npm run format
to format the ./src
source files with Prettier.
Create a .env
(or set env vars in your hosting environment) with at least the following values:
DATABASE_URL
β Postgres connection stringGITHUB_CLIENT_ID
β GitHub OAuth client idGITHUB_CLIENT_SECRET
β GitHub OAuth client secretAUTH_SECRET
β NextAuth secret (used by NextAuth)NEXT_PUBLIC_APP_URL
β public application URL (used for metadata/OG)IP_HASH_SALT
β optional salt used to hash visitor IPs (default placeholder exists in code)
Example (not checked in):
DATABASE_URL=postgresql://user:pass@localhost:5432/snippets
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
AUTH_SECRET=...
NEXT_PUBLIC_APP_URL=http://localhost:3001
IP_HASH_SALT=change-this-in-production
The project uses Drizzle ORM and the schema is defined in src/db/schema.ts
. Main tables include:
users
β stores user profile and settings (jsonb settings object)snippets
β stores snippets: id, title, description, code, language, tags (jsonb array), isPublic, shareId, viewCount, userIdsnippet_views
β tracks views (hashed IP + optional userId) for deduplicationsnippet_likes
β likes for public snippets (by user or by hashed IP)snippet_bookmarks
β bookmarks association table between users and snippets
There are drizzle-kit scripts in package.json
to generate migrations and push them to the database.
Authentication is implemented with NextAuth in src/lib/auth.ts
using the GitHub provider and a Drizzle adapter. Sessions are stored in a database-backed session table. New users receive default settings on first sign-in.
The session callback attaches user.id
and a small settings payload to the session object.
src/lib/shiki.ts
β Shiki-based highlighting service with caching, language and theme fallbacks, and preloading logic. The service exposes functions to highlight code and list available themes/languages.src/lib/detect-lang.ts
β a deterministic, signature-based language detector used for fallback detection.src/lib/security.ts
β helpers to generate secure share IDs (nanoid with custom alphabet), validate them, hash IP addresses (SHA-256, truncated) and retrieve client IP from request headers.
The app exposes several Next.js route handlers under src/app/api
. The important endpoints are:
Authentication (NextAuth):
GET|POST /api/auth/*
β NextAuth routes (sign in, callback, session, sign out, etc.)
Snippets management (requires authenticated session):
GET /api/snippets
β list a user's snippets (supports search, language filter, tags, pagination)POST /api/snippets
β create a new snippetGET /api/snippets/:id
β read a user's snippetPUT /api/snippets/:id
β update a snippet (can toggle public/shareId generation)DELETE /api/snippets/:id
β delete a snippetPOST /api/snippets/:id/bookmark
β bookmark a snippetDELETE /api/snippets/:id/bookmark
β remove bookmark
Public/shared snippet actions (shareId-based):
GET /api/snippets/share/:shareId
β fetch a public snippet by shareId (includes likes info)POST /api/snippets/share/:shareId
β copy a public snippet into the authenticated user's libraryPOST /api/snippets/share/:shareId/view
β track a view (deduplicates by user or hashed IP)POST /api/snippets/share/:shareId/like
β like a public snippet (by user or by hashed IP)DELETE /api/snippets/share/:shareId/like
β unlike
Utility endpoints:
POST /api/detect-language
β quick language detection using highlight.js (body: { code })GET /api/health
β basic health checkGET|PUT /api/settings
β user settings endpoint (server-side)GET /api/settings/public-seo
β public SEO settings endpoint
When calling API endpoints that modify user data, the code checks the authenticated session using the auth()
helper exported by the NextAuth config.
Error handling: most routes return JSON errors with appropriate HTTP status codes (401 for unauthorized, 404 for not found, 400 for validation errors and 500 for server errors).
Prerequisites:
- Node.js / npm (the repo uses npm scripts and Next.js). The codebase expects Node compatible with Next 15.
- PostgreSQL database running and reachable via
DATABASE_URL
.
Local steps:
- Install dependencies
npm install
-
Create
.env
with the variables listed above. -
Run database migrations
npm run migrate
- Start the dev server
npm run dev
The app will start in development mode (default port configured in scripts is 3001). Visit http://localhost:3001
(or the URL configured in NEXT_PUBLIC_APP_URL
).
To build a production bundle:
npm run build
npm run start
Deployment notes:
- Environment variables must be set in the production environment (database, GitHub OAuth, AUTH_SECRET, app URL, IP hash salt).
- The project contains drizzle-kit commands for migrations. Run them as part of your deployment workflow.
- The app uses the Next.js App Router. Server route handlers live in
src/app/api/*
. - The database schema in
src/db/schema.ts
uses typed jsonb settings and sensible defaults for new users. - Syntax highlighting is handled server-side with a Shiki service that caches rendered HTML. For language detection there is a light-weight
detect-language
route using highlight.js. - Share IDs are a 24-character nanoid using a custom alphabet and validated before use.
- The repository includes ESLint and Prettier configuration. Run
npm run lint
andnpm run format
before committing. - There are no unit tests included in the repository snapshot; if you add tests, prefer Jest or Vitest for fast feedback.
If you want to contribute:
- Fork the repository.
- Create a branch for your feature/fix.
- Run lint/format and ensure TypeScript types are satisfied.
- Open a PR targeting the
master
branch (current working branch here isv2
).
When adding features that change the database, add a Drizzle migration (drizzle-kit) and include migration instructions in your PR.
This project is released under the MIT license. See the LICENSE
file for details.
- Entry UI and pages:
src/app/*
(landing page, dashboard, API routes undersrc/app/api
). - Auth & session:
src/lib/auth.ts
. - DB schema:
src/db/schema.ts
. - Highlighting and language utilities:
src/lib/shiki.ts
,src/lib/detect-lang.ts
. - Security helpers (share ID, IP hashing):
src/lib/security.ts
.
If you want a specific section expanded (examples, full API docs, or deployment recipe for a cloud provider), tell me which target environment and I will add a tailored guide.
- Create an issue for bug reports
- Start a discussion for questions