Discover / GTM & Growth

Kutt

by thedevs-networkJavaScript

Modern open source URL shortener with click tracking and analytics

Toolstable

Maturity: stable because 8y old, v3.2.6 released 29d ago. Derived from release and commit history, not a rating.

Stars
11k
Forks
1.5k
Downloads / mo
Last commit
2026-07-05
License
MIT
Open issues
77

Market and trust evidence

Edition not yet matched

No exact skills.sh identity match is available for this repository. Repository adoption and freshness remain visible above; install momentum is not inferred.

Trust analysis is a screening signal, not a security warranty. Read the ranking and trust methodology.

In practice

Written by AI from this repository’s README · high confidence

You want branded short links with per link passwords and expiry without handing the data to a SaaS.

Use it when

Use it when you want a Node.js shortener that runs with zero configuration on SQLite and scales to Postgres.

Not the right pick when

JWT_SECRET is required in production, and registration relies on email, so it needs configuration before going live.

Capabilities

  • custom domain support
  • custom URLs, password, description and expiration time per link
  • private statistics for shortened URLs
  • admin page to manage users and links
  • OpenID Connect login and the ability to disable registration or anonymous links
  • RESTful API with several docker compose configurations for SQLite, Postgres or MariaDB

Requirements

  • Node.js version 20 or above
  • JWT_SECRET set in production
  • optionally Postgres, MySQL/MariaDB or Redis

Cost: Free and open source

Install

Derived from the published package name in the repository, not from a model.

Video walkthroughs

Third-party YouTube uploads matched to this tool by title, channel and repository name on 2026-08-03. Not made, reviewed or endorsed by SkillPilot. View counts and publish months are as of the match date and the month is approximate. Nothing loads from YouTube until you press play.

What the repository ships

Has docsDocker imageCI configured

Detected from the actual files in the repository root.

Latest release v3.2.6

Published 2026-07-05

  • Add OIDC_PROMPT. Fixes OIDC forced re-authentication by making the prompt configurable. (PR #967 by @Jignesh4611)
  • Add OIDC_BUTTON_TEXT to change OIDC login button text
  • Use a new useragent library (express-useragent) to parse user agent. Fixes vulnerabilities found in the useragent package
  • Update nodemailer package to fix vulnerabilities
  • Set SameSite: Lax for signed-in cookies
  • Use 404 HTTP status code for the 404 page
  • Fix typo in the report page

Tags

README

<p align="center"><a href="https://kutt.to" title="kutt.to"><img src="https://raw.githubusercontent.com/thedevs-network/kutt/9d1c873897c3f5b9a1bd0c74dc5d23f2ed01f2ec/static/images/logo-github.png" alt="Kutt.to"></a></p>

Kutt.to

Kutt is a modern URL shortener with support for custom domains. Create and edit links, view statistics, manage users, and more.

https://kutt.to

[!WARNING]

kutt.it is NOT OWNED BY US. It could be a phishing site. We had the domain but it has been deactivated by the Italian TLD registrar due to the lack of identification documents, and now it's owned by someone else.

Please use kutt.to, all the previous and the future links work with this domain as well.

docker-build-release

Uptime Status

Contributions

GitHub license

Table of contents

  • Key features
  • Donations and sponsors
  • Setup
  • Docker
  • API
  • Configuration
  • Themes and customizations
  • Browser extensions
  • Videos
  • Integrations
  • Contributing

Key features

  • Created with self-host in mind:
  • Zero configuration needed
  • Easy setup with no build step
  • Supporting various databases (SQLite, Postgres, MySQL)
  • Ability to disable registration and anonymous links
  • OpenID Connect (OIDC) login
  • Custom domain support
  • Set custom URLs, password, description, and expiration time for links
  • View, edit, delete and manage your links
  • Private statistics for shortened URLs
  • Admin page to manage users and links
  • Customizability and themes
  • RESTful API

Donations and sponsors

Support the development of Kutt by making a donation or becoming an sponsor.

Donate or sponsor →

Setup

The only prerequisite is Node.js (version 20 or above). The default database is SQLite. You can optionally install Postgres or MySQL/MariaDB for the database or Redis for the cache.

When you first start the app, you're prompted to create an admin account.

  1. Clone this repository or download the latest zip
  2. Install dependencies: npm install
  3. Initialize database: npm run migrate
  4. Start the app for development npm run dev or production npm start

Docker

Make sure Docker is installed, then you can start the app from the root directory:


docker compose up

Various docker-compose configurations are available. Use docker compose -f <file_name> up to start the one you want:

  • docker-compose.yml: Default Kutt setup. Uses SQLite for the database.
  • docker-compose.sqlite-redis.yml: Starts Kutt with SQLite and Redis.
  • Required environment variable: REDIS_ENABLED
  • docker-compose.postgres.yml: Starts Kutt with Postgres and Redis.
  • Required environment variables: REDIS_ENABLED, DB_PASSWORD, DB_NAME, DB_USER
  • docker-compose.mariadb.yml: Starts Kutt with MariaDB and Redis.
  • Required environment variables: REDIS_ENABLED, DB_PASSWORD, DB_NAME, DB_USER, DB_PORT

Official Kutt Docker image is available on Docker Hub.

API

View API documentation →

Configuration

The app is configured via environment variables. You can pass environment variables directly or create a .env file. View .example.env file for the list of configurations.

All variables are optional except JWT_SECRET which is required on production.

You can use files for each of the variables by appending _FILE to the name of the variable. Example: JWT_SECRET_FILE=/path/to/secret_file.

| Variable | Description | Default | Example |

| -------- | ----------- | ------- | ------- |

| JWT_SECRET | This is used to sign authentication tokens. Use a long random string. | - | - |

| PORT | The port to start the app on | 3000 | 8888 |

| SITE_NAME | Name of the website | Kutt | Your Site |

| DEFAULT_DOMAIN | The domain address that this app runs on | localhost:3000 | yoursite.com |

| LINK_LENGTH | The length of of shortened address | 6 | 5 |

| LINK_CUSTOM_ALPHABET | Alphabet used to generate custom addresses. Default value omits o, O, 0, i, I, l, 1, and j to avoid confusion when reading the URL. | (abcd..789) | abcABC^&*()@ |

| DISALLOW_REGISTRATION | Disable registration. Note that if MAIL_ENABLED is set to false, then the registration would still be disabled since it relies on emails to sign up users. | true | false |

| DISALLOW_LOGIN_FORM | Disable login with email and password. Only makes sense if OIDC is enabled. | false | true |

| DISALLOW_ANONYMOUS_LINKS | Disable anonymous link creation | true | false |

| TRUST_PROXY | If the app is running behind a proxy server like NGINX or Cloudflare and that it should get the IP address from that proxy server. If you're not using a proxy server then set this to false, otherwise users can override their IP address. | true | false |

| DB_CLIENT | Which database client to use. Supported clients: pg or pg-native for Postgres, mysql2 for MySQL or MariaDB, sqlite3 and better-sqlite3 for SQLite. NOTE: pg-native and sqlite3 are not installed by default, use npm to install them before use. | better-sqlite3 | pg |

| DB_FILENAME | File path for the SQLite database. Only if you use SQLite. | db/data | /var/lib/data |

| DB_HOST | Database connection host. Only if you use Postgres or MySQL. | localhost | your-db-host.com |

| DB_PORT | Database port. Only if you use Postgres or MySQL. | 5432 (Postgres) | 3306 (MySQL) |

| DB_NAME | Database name. Only if you use Postgres or MySQL. | kutt | mydb |

| DB_USER | Database user. Only if you use Postgres or MySQL. | postgres | myuser |

| DB_PASSWORD | Database password. Only if you use Postgres or MySQL. | - | mypassword |

| DB_SSL | Whether use SSL for the database connection. Only if you use Postgres or MySQL. | false | true |

| DB_POOL_MIN | Minimum number of database connection pools. Only if you use Postgres or MySQL. | 0 | 2 |

| DB_POOL_MAX | Maximum number of database connection pools. Only if you use Postgres or MySQL. | 10 | 5 |

| REDIS_ENABLED | Whether to use Redis for cache | false | true |

| REDIS_HOST | Redis connection host | 127.0.0.1 | your-redis-host.com |

| REDIS_PORT | Redis port | 6379 | 6379 |

| REDIS_PASSWORD | Redis password | - | mypassword |

| REDIS_DB | Redis database number, between 0 and 15. | 0 | 1 |

| SERVER_IP_ADDRESS | The IP address shown to the user on the setting's page. It's only for display purposes and has no other use. | - | 1.2.3.4 |

| SERVER_CNAME_ADDRESS | The subdomain shown to the user on the setting's page. It's only for display purposes and has no other use. | - | custom.yoursite.com |

| CUSTOM_DOMAIN_USE_HTTPS | Use https for links with custom domain. It's on you to generate SSL certificates for those domains manually—at least on this version for now. | false | true |

| ENABLE_RATE_LIMIT | Enable rate limiting for some API routes. If Redis is enabled uses Redis, otherwise, uses memory. | false | true |

| MAIL_ENABLED | Enable emails, which are used for signup, verifying or changing email address, resetting password, and sending reports. If is disabled, all these functionalities will be disabled too. | false | true |

| MAIL_HOST | Email server host | - | your-mail-server.com |

| MAIL_PORT | Email server port | 587 | 465 (SSL) |

| MAIL_USER | Email server user | - | myuser |

| MAIL_PASSWORD | Email server password for the user | - | mypassword |

| MAIL_FROM | Email address to send the user from | - | example@yoursite.com |

| MAIL_SECURE | Whether use SSL for the email server connection | false | true |

| OIDC_ENABLED | Enable OpenID Connect | false | true |

| OIDC_ISSUER | OIDC issuer URL | - | https://example.com/some/path |

| OIDC_POMPT | OIDC prompt | - | login |

| OIDC_CLIENT_ID | OIDC client id | - | example-app |

| OIDC_CLIENT_SECRET | OIDC client secret | - | some-secret |

| OIDC_SCOPE | OIDC Scope | openid profile email | openid email |

| OIDC_EMAIL_CLAIM | Name of the field to get user's email from | email | userEmail |

| OIDC_BUTTON_TEXT | OIDC login button text | Log in with OIDC | Log in via Example |

| REPORT_EMAIL | The email address that will receive submitted reports | - | example@yoursite.com |

| CONTACT_EMAIL | The support email address to show on the app | - | example@yoursite.com |

Themes and customizations

You can add styles, change images, or render custom HTML. Place your content inside the /custom folder according to below instructions.

How it works:

The structure of the custom folder is like this:


custom/
├─ css/
│  ├─ custom1.css
│  ├─ custom2.css
│  ├─ ...
├─ images/
│  ├─ logo.png
│  ├─ favicon.ico
│  ├─ ...
├─ views/
│  ├─ partials/
│  │  ├─ footer.hbs
│  ├─ 404.hbs
│  ├─ ...
  • css: Put your CSS style files here. (View example →)
  • You can put as many style files as you want: custom1.css, custom2.css, etc.
  • If you name your style file styles.css, it will replace Kutt's original styles.css file.
  • Each file will be accessible by <your-site.com>/css/<file>.css
  • images: Put your images here. (View example →)
  • Name them just like the files inside the /static/images/ folder to replace Kutt's original images.
  • Each image will be accessible by <your-site.com>/images/<image>.<image-format>
  • views: Custom HTML templates to render. (View example →)
  • It should follow the same file naming and folder structure as /server/views
  • Although we try to keep the original file names unchanged, be aware that new changes on Kutt might break your custom views.
Example theme: Crimson

This is an example and official theme. Crimson includes custom styles, images, and views.

Get Crimson theme →

View list of themes and customizations →

| Homepage | Admin page | Login/signup |

| -------- | ---------- | ------------ |

| crimson-homepage | crimson-admin | crimson-login-signup

Usage with Docker:

If you're building the image locally, then the /custom folder should already be included in your app.

If you're pulling the official image, make sure /kutt/custom volume is mounted or you have access to it. View Docker compose example →

Then, move your files to that volume. You can do it with this Docker command:


docker cp <path-to-custom-folder> <kutt-container-name>:/kutt

For example:


docker cp custom kutt-server-1:/kutt

Make sure to restart the kutt server container after copying files or making changes.

Browser extensions

Download Kutt's extension for web browsers via below links.

Videos

Official videos

Integrations

  • ShareX – You can use Kutt as your default URL shortener in ShareX. If you host your custom instance of Kutt, refer to ShareX wiki on how to setup.
  • Alfred workflow – Download Kutt's official workflow for Alfred app from alfred-kutt repository.
  • iOS shortcutKutt shortcut for your apple device which works from the iOS sharing context menu or on standalone mode. A courtesy of @caneeeeee.

Third-party packages

| Language | Link | Description |

| --------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------- |

| C# (.NET) | KuttSharp | .NET package for Kutt.to url shortener

Truncated. Read the full README on GitHub ↗

Related tools