npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@linkforty/core

v1.4.2

Published

Open-source deeplink management engine with device detection and analytics

Readme

@linkforty/core

Open-source deeplink management engine with device detection and analytics

LinkForty Core is a powerful, self-hosted deeplink management system that enables you to create, manage, and track smart links with device-specific routing, analytics, and UTM parameter support. It's the open-source foundation of the LinkForty platform.

npm version License: MIT

Features

Smart Link Routing - Create short links with device-specific URLs for iOS, Android, and web
Device Detection - Automatic detection and routing based on user device
Click Analytics - Track clicks with geolocation, device type, platform, and more
UTM Parameters - Built-in support for UTM campaign tracking
Link Expiration - Set expiration dates for time-sensitive links
Redis Caching - Optional Redis support for high-performance link lookups
PostgreSQL Storage - Reliable data persistence with full SQL capabilities
TypeScript - Fully typed API for better developer experience

Installation

npm install @linkforty/core

Quick Start

1. Basic Server

import { createServer } from '@linkforty/core';

async function start() {
  const server = await createServer({
    database: {
      url: 'postgresql://localhost/linkforty',
    },
    redis: {
      url: 'redis://localhost:6379',
    },
  });

  await server.listen({ port: 3000, host: '0.0.0.0' });
  console.log('Server running on http://localhost:3000');
}

start();

2. Self-Hosting with Docker

# Clone the examples
git clone https://github.com/linkforty/core.git
cd core/examples

# Start services
docker compose up -d

# Server will be available at http://localhost:3000

API Reference

Create a Link

POST /api/links
Content-Type: application/json

{
  "userId": "user-uuid",
  "originalUrl": "https://example.com",
  "title": "My Link",
  "iosUrl": "myapp://product/123",
  "androidUrl": "myapp://product/123",
  "webFallbackUrl": "https://example.com/product/123",
  "utmParameters": {
    "source": "twitter",
    "medium": "social",
    "campaign": "summer-sale"
  },
  "customCode": "summer-sale",
  "expiresAt": "2024-12-31T23:59:59Z"
}

Response:

{
  "id": "link-uuid",
  "userId": "user-uuid",
  "short_code": "summer-sale",
  "original_url": "https://example.com",
  "title": "My Link",
  "ios_url": "myapp://product/123",
  "android_url": "myapp://product/123",
  "web_fallback_url": "https://example.com/product/123",
  "utmParameters": {
    "source": "twitter",
    "medium": "social",
    "campaign": "summer-sale"
  },
  "is_active": true,
  "expires_at": "2024-12-31T23:59:59Z",
  "created_at": "2024-01-01T00:00:00Z",
  "updated_at": "2024-01-01T00:00:00Z",
  "clickCount": 0
}

Get All Links

GET /api/links?userId=user-uuid

Get a Specific Link

GET /api/links/:id?userId=user-uuid

Update a Link

PUT /api/links/:id?userId=user-uuid
Content-Type: application/json

{
  "title": "Updated Title",
  "isActive": false
}

Delete a Link

DELETE /api/links/:id?userId=user-uuid

Get Analytics Overview

GET /api/analytics/overview?userId=user-uuid&days=30

Response:

{
  "totalClicks": 1234,
  "uniqueClicks": 567,
  "clicksByDate": [
    { "date": "2024-01-01", "clicks": 45 }
  ],
  "clicksByCountry": [
    { "countryCode": "US", "country": "United States", "clicks": 234 }
  ],
  "clicksByDevice": [
    { "device": "mobile", "clicks": 789 }
  ],
  "clicksByPlatform": [
    { "platform": "iOS", "clicks": 456 }
  ],
  "topLinks": [
    {
      "id": "link-uuid",
      "shortCode": "summer-sale",
      "title": "My Link",
      "originalUrl": "https://example.com",
      "totalClicks": 123,
      "uniqueClicks": 67
    }
  ]
}

Get Link-Specific Analytics

GET /api/analytics/links/:linkId?userId=user-uuid&days=30

Redirect Short Link

GET /:shortCode

This endpoint automatically redirects users to the appropriate URL based on their device type.

Configuration

Server Options

interface ServerOptions {
  database?: {
    url?: string;           // PostgreSQL connection string
    pool?: {
      min?: number;         // Minimum pool connections (default: 2)
      max?: number;         // Maximum pool connections (default: 10)
    };
  };
  redis?: {
    url: string;            // Redis connection string (optional)
  };
  cors?: {
    origin: string | string[];  // CORS allowed origins (default: '*')
  };
  logger?: boolean;         // Enable Fastify logger (default: true)
}

Environment Variables

DATABASE_URL=postgresql://localhost/linkforty
REDIS_URL=redis://localhost:6379
PORT=3000
NODE_ENV=production
CORS_ORIGIN=*

Database Schema

Users Table

| Column | Type | Description | |---------------|--------------|-----------------------| | id | UUID | Primary key | | email | VARCHAR(255) | Unique email | | name | VARCHAR(255) | User name | | password_hash | VARCHAR(255) | Hashed password | | created_at | TIMESTAMP | Creation timestamp | | updated_at | TIMESTAMP | Last update timestamp |

Links Table

| Column | Type | Description | |------------------|--------------|-----------------------| | id | UUID | Primary key | | user_id | UUID | Foreign key to users | | short_code | VARCHAR(20) | Unique short code | | original_url | TEXT | Original URL | | title | VARCHAR(255) | Link title | | ios_url | TEXT | iOS-specific URL | | android_url | TEXT | Android-specific URL | | web_fallback_url | TEXT | Web fallback URL | | utm_parameters | JSONB | UTM parameters | | targeting_rules | JSONB | Targeting rules | | is_active | BOOLEAN | Active status | | expires_at | TIMESTAMP | Expiration date | | created_at | TIMESTAMP | Creation timestamp | | updated_at | TIMESTAMP | Last update timestamp |

Click Events Table

| Column | Type | Description | |--------------|--------------|------------------------------| | id | UUID | Primary key | | link_id | UUID | Foreign key to links | | clicked_at | TIMESTAMP | Click timestamp | | ip_address | INET | User IP address | | user_agent | TEXT | User agent string | | device_type | VARCHAR(20) | Device type (mobile/desktop) | | platform | VARCHAR(20) | Platform (iOS/Android/Web) | | country_code | CHAR(2) | Country code | | country_name | VARCHAR(100) | Country name | | region | VARCHAR(100) | Region/state | | city | VARCHAR(100) | City | | latitude | DECIMAL | Latitude | | longitude | DECIMAL | Longitude | | timezone | VARCHAR(100) | Timezone | | utm_source | VARCHAR(255) | UTM source | | utm_medium | VARCHAR(255) | UTM medium | | utm_campaign | VARCHAR(255) | UTM campaign | | referrer | TEXT | Referrer URL |

Utilities

Generate Short Code

import { generateShortCode } from '@linkforty/core';

const code = generateShortCode(8); // Returns 8-character nanoid

Detect Device

import { detectDevice } from '@linkforty/core';

const device = detectDevice(userAgent); // Returns 'ios' | 'android' | 'web'

Get Location from IP

import { getLocationFromIP } from '@linkforty/core';

const location = getLocationFromIP('8.8.8.8');
// Returns: { countryCode, countryName, region, city, latitude, longitude, timezone }

Build Redirect URL with UTM Parameters

import { buildRedirectUrl } from '@linkforty/core';

const url = buildRedirectUrl('https://example.com', {
  source: 'twitter',
  medium: 'social',
  campaign: 'summer-sale'
});
// Returns: https://example.com?utm_source=twitter&utm_medium=social&utm_campaign=summer-sale

Advanced Usage

Custom Route Registration

import { createServer } from '@linkforty/core';

const server = await createServer({
  database: { url: 'postgresql://localhost/linkforty' },
});

// Add custom routes
server.get('/custom', async (request, reply) => {
  return { message: 'Hello World' };
});

await server.listen({ port: 3000 });

Using Individual Route Handlers

import Fastify from 'fastify';
import { initializeDatabase, redirectRoutes, linkRoutes } from '@linkforty/core';

const fastify = Fastify();

// Initialize database separately
await initializeDatabase({ url: 'postgresql://localhost/linkforty' });

// Register only specific routes
await fastify.register(redirectRoutes);
await fastify.register(linkRoutes);

await fastify.listen({ port: 3000 });

Deployment

LinkForty can be deployed in multiple ways depending on your needs:

🚀 Production Deployment (Recommended)

Deploy to managed platforms with minimal DevOps overhead:

Fly.io (Recommended)

  • Global edge deployment
  • Managed PostgreSQL and Redis
  • Auto-scaling and SSL included
  • Starting at ~$10-15/month

View Fly.io deployment guide →

See infra/ directory for all deployment options and platform-specific guides.

Docker Deployment (Self-Hosted)

For local development or self-managed infrastructure:

git clone https://github.com/linkforty/core.git
cd core/examples
docker compose up -d

See examples/docker-compose.yml for complete Docker setup.

Manual Deployment

For custom infrastructure needs:

  1. Install dependencies: npm install @linkforty/core
  2. Set up PostgreSQL database (13+)
  3. Set up Redis (optional but recommended)
  4. Run migrations: npm run migrate
  5. Start server: node server.js

Other Platforms

Community-maintained templates available for:

  • AWS (ECS/Fargate)
  • Google Cloud Run
  • Railway, Render, and more

See infra/CONTRIBUTING.md to add support for additional platforms.

Performance

  • Redis caching: 5-minute TTL on link lookups reduces database queries by 90%
  • Database indexes: Optimized queries for fast link lookups and analytics
  • Async click tracking: Non-blocking click event logging
  • Connection pooling: Efficient database connection management

Security

  • SQL injection protection: Parameterized queries throughout
  • Input validation: Zod schema validation on all inputs
  • CORS configuration: Configurable CORS for API access control
  • Link expiration: Automatic handling of expired links

Roadmap

  • [ ] Webhook support for click events
  • [ ] Bulk link operations via API
  • [ ] Link grouping and tags
  • [ ] A/B testing support
  • [ ] QR code generation
  • [ ] Custom domain support (in SaaS version)

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

License

MIT License - see LICENSE file for details.

Related Projects

  • @linkforty/ui - React UI components for link management
  • LinkForty Cloud - Hosted SaaS version with additional features

Support

Built with: