Tech Stack Review

Short URL

A small full-stack URL shortener built with Next.js App Router. It uses a password-gated admin screen to create and delete links, stores slug records in Redis, falls back to in-memory storage in local development, and resolves public <code>/{slug}</code> requests through a redirect route.

Main Stack

The core pieces that make the branded short-link workflow work.

Framework

Next.js 16 App Router

The app is built with Next.js using the App Router. Page rendering, route handlers, redirects, and server actions all live inside the same framework structure.

UI

React 19 admin screen

The main interface is a small React-based admin UI for creating and deleting short links. It is intentionally compact and focused on one operational task instead of acting like a broader dashboard.

Styling

Tailwind CSS v4

The interface styling is handled with Tailwind utility classes and shared tokens in app/globals.css. The result is a minimal dark UI with orange accents and lightweight form styling.

Backend pattern

Server actions + route handler

Mutations such as login, logout, create, and delete live in app/actions.ts, while the public redirect is handled by a dedicated route file rather than a separate API service.

Storage

Redis with local memory fallback

Link records are stored through the abstraction in lib/redis.ts. In production it connects to Redis through <code>ioredis</code>, and in local development it can fall back to an in-memory Map when <code>REDIS_URL</code> is missing.

Auth

Cookie session + admin token

Authentication is intentionally simple: a password is checked against ADMIN_TOKEN , then persisted as an HTTP-only cookie using helpers in lib/auth.ts.

How It Runs

The runtime path from opening the admin screen to resolving a short link.

1

The admin page checks authentication first

The main page in app/page.tsx calls the auth helper before rendering. Unauthenticated users are redirected to the login page.

2

Server actions handle login and link mutations

The form flows are wired to server actions in app/actions.ts . Those actions validate input, check auth, generate slugs when needed, and trigger cache revalidation for the admin page.

3

Slug creation uses validation plus base62 generation

Custom slugs are validated with helpers in lib/slug.ts . If no slug is supplied, the app tries several random base62 candidates until it finds one that is unused.

4

Links are stored and listed from the storage layer

The Redis layer stores each link record, keeps an index of slugs, and returns the list ordered by creation date. The same interface is also used by the in-memory fallback store for local work without Redis.

5

Public slug requests redirect through a route handler

Incoming requests to app/[slug]/route.ts look up the slug and issue the redirect. If the slug does not exist, the route returns a 404 response.

Architecture Map

The repo is small, but each folder has a very specific role.

Key folders
app/Admin page, login page, server actions, shared form components, and the public redirect route.
lib/Authentication helpers, slug validation and generation, and the storage abstraction.
public/Static assets such as the app icon and placeholder SVG files.
.vercel/Local Vercel metadata used for deployment and dev tooling.
Architecture Analysis
app/page.tsx
app/login/page.tsx
app/[slug]/route.ts
app/actions.ts
lib/auth.ts
lib/redis.ts
lib/slug.ts

This app is intentionally narrower than something like Card Tracker. It is not a general CRUD dashboard or a large multi-page product. The core architecture is a small authenticated admin workflow paired with a single public redirect endpoint and a thin storage abstraction.

Data and Storage

Persistence is simple and centered on slug records.

Stored record

A link is just slug, URL, and timestamp

Each link record stores the slug, destination URL, and creation time.

Redis keys are namespaced per slug and tracked through a sorted index.

Listing links is based on that index rather than a relational query layer.

There is no database schema, ORM, or migration system in this project.

Fallback mode

Local development can run without Redis

If REDIS_URL is not configured, the app logs a warning and uses an in-memory Map.

That fallback keeps local setup easy but loses data when the process restarts.

The same store interface is used for both Redis and memory, so the rest of the app stays unchanged.

This makes the project especially lightweight to boot locally.

Routing and Request Flow

The interesting part of the app is how admin actions and public redirects share one codebase.

Admin surface
app/page.tsx + app/login/

The admin side uses server-rendered pages with auth checks, simple forms, and server actions for all state changes. There is no separate client API layer for the core workflows.

Redirect surface
app/[slug]/route.ts

The public side is a route handler that receives the slug, looks it up in the storage layer, and redirects to the destination URL. That keeps the public behavior extremely small and direct.

Run Commands

The local workflow is intentionally minimal.

Scripts
npm install
npm run dev

npm run build
npm start

The project uses the standard Next.js cycle: npm run dev for local development and npm run build for production verification.

Environment setup

What the app expects

ADMIN_TOKEN is required for logging into the admin UI.

REDIS_URL is used for Redis-backed persistence in production and can be omitted for local in-memory mode.

Node.js, npm, and the standard Next.js toolchain are enough to run the app.

No external auth provider, ORM, or background job system is required.

Bottom Line

Short URL is a small Next.js full-stack utility built around server actions, cookie auth, Redis-backed link storage, and a direct redirect route. Its strength is not complexity but focus: one branded admin workflow, one public slug endpoint, and a very low-friction local setup.