{"id":42268781,"url":"https://github.com/krizzu/shortie","last_synced_at":"2026-01-27T07:09:53.073Z","repository":{"id":331703259,"uuid":"1118793139","full_name":"krizzu/shortie","owner":"krizzu","description":"A minimal, self-hostable URL shortening service with an admin dashboard for managing links.","archived":false,"fork":false,"pushed_at":"2026-01-20T22:47:20.000Z","size":429,"stargazers_count":2,"open_issues_count":13,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-21T08:36:24.556Z","etag":null,"topics":["api","coroutines","docker","docker-compose","kotlin","ktor","ktor-server","link-shortener","postgresql","react","self-hosted","tanstack-query","tanstack-router"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/krizzu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-18T09:35:08.000Z","updated_at":"2026-01-20T22:47:23.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/krizzu/shortie","commit_stats":null,"previous_names":["krizzu/shortie"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/krizzu/shortie","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krizzu%2Fshortie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krizzu%2Fshortie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krizzu%2Fshortie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krizzu%2Fshortie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/krizzu","download_url":"https://codeload.github.com/krizzu/shortie/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krizzu%2Fshortie/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28807416,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T06:25:51.065Z","status":"ssl_error","status_checked_at":"2026-01-27T06:25:50.640Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","coroutines","docker","docker-compose","kotlin","ktor","ktor-server","link-shortener","postgresql","react","self-hosted","tanstack-query","tanstack-router"],"created_at":"2026-01-27T07:09:48.797Z","updated_at":"2026-01-27T07:09:53.064Z","avatar_url":"https://github.com/krizzu.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg height=\"100\" src=\"assets/shortie-logo.png\" alt=\"shortie-logo\" align=\"center\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eA minimal, self-hostable URL shortening service with an admin dashboard for managing links.\u003c/b\u003e\u003cbr\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Kotlin-2.2.20-7F52FF?logo=kotlin\u0026logoColor=white\" alt=\"Kotlin 2.2.20\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Ktor-3.3.2-0095D5?logo=ktor\u0026logoColor=white\" alt=\"Ktor 3.3.2\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Coroutines-1.10.2-0095D5\" alt=\"Kotlin Coroutines 1.10.2\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Koin-4.1.1-FE7A16\" alt=\"Koin 4.1.1\" /\u003e\n  \u003cbr/\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Exposed-1.0.0--rc--4-000000\" alt=\"Exposed 1.0.0-rc-4\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/HikariCP-7.0.2-2C2C2C\" alt=\"HikariCP 7.0.2\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Flyway-10.22.0-CC0200?logo=flyway\u0026logoColor=white\" alt=\"Flyway 10.22.0\" /\u003e\n  \u003cbr/\u003e\n  \u003cimg src=\"https://img.shields.io/badge/PostgreSQL-Database-336791?logo=postgresql\u0026logoColor=white\" alt=\"PostgreSQL\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Docker-Friendly-2496ED?logo=docker\u0026logoColor=white\" alt=\"Docker Friendly\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/License-Apache_2.0-blue.svg\" alt=\"License: Apache 2.0\" /\u003e\n\u003c/p\u003e\n\n## Features\n\n- Short-code based URLs for compact links\n- Custom aliases for human-readable links\n- Expiring links with expiration dates\n- Password protected links\n- Modern admin dashboard with a easy UI\n- Docker friendly set up\n\n## Getting started\n\nCopy content from `.env-example` file into `.env`.\nRun docker via `docker compose up -d`.\n\nExample `compose.yaml` file:\n\n```yaml\nservices:\n  db:\n    image: postgres:18.1\n    container_name: db\n    restart: unless-stopped\n    volumes:\n      - postgres_data:/var/lib/postgresql\n    environment:\n      POSTGRES_DB: ${APP_DB_NAME}\n      POSTGRES_USER: ${APP_DB_USER}\n      POSTGRES_PASSWORD: ${APP_DB_PASSWORD}\n    healthcheck:\n      test: [ \"CMD-SHELL\", \"pg_isready -U ${APP_DB_USER} -d ${APP_DB_NAME}\" ]\n      interval: 1s\n\n  shortie:\n    image: krizzu/shortie:dev # or other tag\n    container_name: app\n    restart: unless-stopped\n    ports:\n      - \"80:80\" # api port\n      - \"81:81\" # dashboard port\n    depends_on:\n      - db\n    environment:\n      APP_DB_URL: jdbc:postgresql://db:5432/${APP_DB_NAME}\n      APP_DB_PASSWORD: ${APP_DB_PASSWORD}\n      APP_DB_USER: ${APP_DB_USER}\n      APP_ID_ALPHABET: ${APP_ID_ALPHABET}\n      APP_AUTH_SECRET: ${APP_AUTH_SECRET}\n      APP_ADMIN_PASSWORD: ${APP_ADMIN_PASSWORD}\n\n      # keep this in sync with exposed api port on host for proper redirections\n      # defaults to 80\n      #APP_API_PROXY_PORT: 4000\n\nvolumes:\n  postgres_data:\n```\n\n## Tech stack\n\n- Kotlin + Ktor → HTTP server and routing\n- Exposed + HikariCP + Flyway → Database access, pooling and migrations\n- Koin → Dependency injection\n- TypeScript + React → Frontend\n- Tanstack Router → Frontend router\n- Tailwind CSS → Styling\n\n\n## Local development\n\nSee [DEVELOPMENT.md](./DEVELOPMENT.md) guide.\n\n## License\n\n```\nCopyright 2026 Krzysztof Borowy\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrizzu%2Fshortie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkrizzu%2Fshortie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrizzu%2Fshortie/lists"}