https://github.com/alexthemaster/pokole
URL shortening done using Node.js and PostgreSQL
https://github.com/alexthemaster/pokole
bitly js-url-shortener pokole postgresql tinyurl url url-shortener yourls
Last synced: 12 days ago
JSON representation
URL shortening done using Node.js and PostgreSQL
- Host: GitHub
- URL: https://github.com/alexthemaster/pokole
- Owner: alexthemaster
- License: mit
- Created: 2019-07-31T17:56:56.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2025-07-22T05:37:45.000Z (7 months ago)
- Last Synced: 2025-08-22T13:27:19.706Z (6 months ago)
- Topics: bitly, js-url-shortener, pokole, postgresql, tinyurl, url, url-shortener, yourls
- Language: TypeScript
- Homepage:
- Size: 1.29 MB
- Stars: 1
- Watchers: 2
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.MD
- License: LICENSE
- Codeowners: CODEOWNERS
Awesome Lists containing this project
README

[](https://lgtm.com/projects/g/alexthemaster/pokole/context:javascript)
# 🔗 Pokole
Pokole is a simple and fast URL shortener that uses NodeJS and PostgreSQL.
## 🤔 Meaning
Pokole stands for 'short' in Hawaiian.
## 💻 Features
- Simplicity
- Ease of use
- In-depth statistics
- Written in TypeScript to ensure fast and bug-free code
## 🐳 Docker
Using Pokole in Docker is easier, faster and more convenient! Head over to [Docker Hub](https://hub.docker.com/r/alexthemaster/pokole) for more information. Web UI built in!
## 📝 Requirements
- [Node.js](https://nodejs.org/en/) (12 or newer)
- [node-gyp](https://github.com/nodejs/node-gyp) (required for building bcrypt)
- [PostgreSQL](https://postgresql.org) (latest)
## 🔨 Usage
Here's an easy-to-follow tutorial:
- Install Node, node-gyp and PostgreSQL
- Create a new folder and install the package inside via npm (`npm install pokole`) or yarn (`yarn add pokole`)
- Create a JavaScript file inside the folder (e.g. `server.js`)
- Import the Pokole class from the package, create a new instance of the class, provide the required configuration and call the `.start()` function! You can find a sample script below:
```js
// We import the Pokole class from the Pokole package
const { Pokole } = require("pokole");
// You need to provide an object containing crucial information for the package, so we define it here
const config = {
// The database connection information
db: {
// The database user
user: "alexthemaster",
// The password used by the PostgreSQL user
password: "eee23EfgZ",
// The URL PostgreSQL can be accessed from
host: "localhost",
// The name of the database to use from PostgreSQL
database: "pokole",
// The port PostgreSQL uses (defaults to 5432)
port: 5432,
},
// The URL the Pokole can be accessed from
URL: "localhost",
server: {
// The port Pokole should run on, (defaults to 80)
port: 80,
},
// The JWT (JSON Web Token) secret you want to use - make sure to keep this private, as this is what's used to encrypt user tokens
jwtSecret: "33HdAiM$4zGs",
// Whether or not registration is enabled, defaults to true
registration: true,
};
// We create a new Pokole instance, provide it with the required options and call the start function
new Pokole(config).start();
```
⚠ We recommend using a process manager such as [PM2](https://pm2.keymetrics.io) to keep the script running!
## 📂 Hosting Static Files
If you want to host static files alongside Pokole, create a folder called `static` in the folder above and Pokole will serve the files inside this folder.
[Pokole-Web](https://github.com/alexthemaster/pokole-web) is the default web dashboard included in the Docker build.
## 🕸 Routes / API
| Endpoint | Type | Headers | Body | Description | Returns (JSON) | Requires authentication |
| ------------------- | ------ | --------------------------------------------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ----------------------- |
| /api/register | GET | | | Check if registration is possible | `{ enabled: boolean }` | No |
| /api/register | POST | `Content-Type: "application/json"` | `{ email: string, username: string, password: string }` | Register an account | `{ success: string } \| { error: string }` | No |
| /api/login | POST | `Content-Type: "application/json"` | `{ username: string, password: string }` | Login to an existing account | `{ token: string, expiresIn: number } \| error: string` | No |
| /api/shorten | POST | `Authorization: Bearer token, Content-Type: "application/json"` | `{ url: string, custom?: string }` | Shorten an URL | `{ success: string, URL: link } \| error: string` | Yes |
| /api/me/links | GET | `Authorization: Bearer token` | | Returns an array containing the list of your shortened URL's and and array of statistics for it | `{ longURL: link, shortURL: link, created_on: date, stats: [] }` | Yes |
| /api/me/links/:link | DELETE | `Authorization: Bearer token, Content-Type: "application/json"` | | Delete a shortlink | `{ success: string } \| { error: string }` | Yes |
Legend: `?` means the header is optional; `|` means OR; the string after `:` in the Returns column is the type of the returned object
Note: the token is only valid for an hour, so you will have to request a new one after that!