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.
β
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
npm install @linkforty/coreimport { 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();# 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:3000POST /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 /api/links?userId=user-uuidGET /api/links/:id?userId=user-uuidPUT /api/links/:id?userId=user-uuid
Content-Type: application/json
{
"title": "Updated Title",
"isActive": false
}DELETE /api/links/:id?userId=user-uuidGET /api/analytics/overview?userId=user-uuid&days=30Response:
{
"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 /api/analytics/links/:linkId?userId=user-uuid&days=30GET /:shortCodeThis endpoint automatically redirects users to the appropriate URL based on their device type.
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)
}DATABASE_URL=postgresql://localhost/linkforty
REDIS_URL=redis://localhost:6379
PORT=3000
NODE_ENV=production
CORS_ORIGIN=*| Column | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| 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 |
| 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 |
| 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 |
import { generateShortCode } from '@linkforty/core';
const code = generateShortCode(8); // Returns 8-character nanoidimport { detectDevice } from '@linkforty/core';
const device = detectDevice(userAgent); // Returns 'ios' | 'android' | 'web'import { getLocationFromIP } from '@linkforty/core';
const location = getLocationFromIP('8.8.8.8');
// Returns: { countryCode, countryName, region, city, latitude, longitude, timezone }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-saleimport { 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 });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 });LinkForty can be deployed in multiple ways depending on your needs:
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.
For local development or self-managed infrastructure:
git clone https://github.com/linkforty/core.git
cd core/examples
docker-compose up -dSee examples/docker-compose.yml for complete Docker setup.
For custom infrastructure needs:
- Install dependencies:
npm install @linkforty/core - Set up PostgreSQL database (13+)
- Set up Redis (optional but recommended)
- Run migrations:
npm run migrate - Start server:
node server.js
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.
- 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
- 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
- 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)
Contributions are welcome! Please see CONTRIBUTING.md for details.
MIT License - see LICENSE file for details.
- @linkforty/ui - React UI components for link management
- LinkForty Cloud - Hosted SaaS version with additional features
- Documentation: https://docs.linkforty.com
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Fastify - Fast web framework
- PostgreSQL - Powerful database
- Redis - In-memory cache
- nanoid - Unique ID generation
- geoip-lite - IP geolocation
- ua-parser-js - User agent parsing