TFDL is a local-first launcher for browser-based utility tools (formatters, timers, calculators, writing helpers, media tools, and more). It is designed for fast keyboard use, predictable paths, and zero frontend build tooling.
You can use it in two ways:
- Static mode: open
index.htmldirectly and use canonical tool pages undertools/ - Server mode (recommended): run the included Go server for
/t/<alias>/shortcuts, optional Basic Auth, and/healthz
- Keyboard-first launcher (
/,j/k,Enter,p,y,Y,1-0,v) - Registry-driven dashboard from
assets/js/tools.registry.js - Stable canonical paths:
tools/<category>/<slug>/ - Short aliases:
/t/<alias>/(served dynamically by the Go server) - No Node build step required
- Docker and Docker Compose support
Download the latest release for your platform from GitHub releases, then:
./tfdl_v1.0.0_linux_amd64
# Serves on http://0.0.0.0:8080 using embedded filesNo configuration needed! Static files are bundled in the binary.
Custom options:
./tfdl -port 3000 # Custom port
./tfdl -root /path/to/files # Serve external files instead of embedded
./tfdl -config ./tfdl.json # Use config file
./tfdl -auth-enabled=true -auth-user dev -auth-pass secret
./tfdl -debug # Enable debug logging
./tfdl version # Show versionPull and run the published image:
docker pull ghcr.io/thecodefreak/tfdl:latest
docker run --rm -p 127.0.0.1:8080:8080 ghcr.io/thecodefreak/tfdl:latest
# Serves on http://127.0.0.1:8080 using embedded filesUse a pinned release tag when you want a fixed version:
docker pull ghcr.io/thecodefreak/tfdl:0.2.0
docker run --rm -p 127.0.0.1:8080:8080 ghcr.io/thecodefreak/tfdl:0.2.0Requirements: Go 1.25+ (see go.mod)
go build -o tfdl ./cmd/tfdl
./tfdlOption 1: Fast iteration with go run (recommended for development)
go run ./cmd/tfdl serve
# Edit HTML/CSS/JS files → just refresh browserWith go run, embedded files are read from disk in real-time, so you can edit and see changes immediately.
Option 2: Build and test
go build -o tfdl ./cmd/tfdl
./tfdl
# Rebuild after making changes to see themCompiled binaries have files frozen at build time.
docker compose up --build
# Edit files → refresh browser (volume mount active)The compose setup mounts project files for easy iteration.
Examples:
TFDL_PORT=9090 docker compose up --buildOpen index.html directly in a browser.
- Works for the launcher UI and canonical tool pages
- Does not support
/t/<alias>/routes (requires server)
TFDL_AUTH_ENABLED=true \
TFDL_AUTH_USER=dev \
TFDL_AUTH_PASS='secret' \
docker compose -f compose.yml up --buildEach tool has:
- A canonical source path:
tools/<category>/<slug>/ - A short alias URL:
/t/<alias>/
Examples:
/t/json/->tools/dev/json-formatter//t/focus/->tools/productivity/focus-timer//t/words/->tools/writing/word-counter/
Aliases are generated dynamically by the Go server from
assets/js/tools.registry.js. The registry is the single source of truth.
- Search by name, alias, category, path, and description
- Token filters such as
@dev,@media,#json,#timer - Pin tools and store recents in browser
localStorage - Copy alias path and source path from the launcher
- Open top visible results with
1..0 - Card and table views with keyboard navigation
index.html- launcher dashboardassets/css/styles.css- shared styling for launcher and toolsassets/css/framework.css- local UI framework primitives/utilitiesassets/css/skins/canva-dark.css- default skinassets/css/user.css- local overrides loaded lastassets/js/tools.registry.js- tool metadata registry (name, alias, category, tags)assets/js/app.js- launcher behavior (search, filters, pins, recents, views)tools/- canonical tool implementations by categorycmd/tfdl/- Go CLI entrypoint (serve,print-config)internal/tfdl/- Go server and config logictfdl.example.json- tracked starter config templatetfdl.json- optional local server config (ignored by git)
- Copy
tools/_template/into the target category and rename it to your slug. - Implement
tools/<category>/<slug>/index.html(and page assets if needed). - Add the tool entry to
assets/js/tools.registry.js. - Reload the launcher and verify:
- search results
- alias path (
/t/<alias>/) - source path link
Recommended quick validation:
node --check assets/js/app.js
node --check assets/js/tools.registry.jsIf you changed a tool script, run node --check on that file too.
The Go server is optional, but enables alias routing and a better local app flow.
Commands:
tfdl serve- run the static file server (default command)tfdl print-config- print the effective config after file + env resolution
Supported serve flags:
-config-port-bind-root-auth-enabled-auth-user-auth-pass
The config file is JSON (no YAML dependency).
The repo includes a tracked template: tfdl.example.json.
Create a local config file from it:
cp tfdl.example.json tfdl.jsonExample:
{
"server": {
"bind": "0.0.0.0",
"port": 8080
},
"auth": {
"enabled": false,
"username": "admin",
"password": ""
}
}Note: root_dir is optional. If omitted (default), embedded files are used. Set it only if you want to serve external files:
{
"server": {
"root_dir": "/path/to/custom/files"
}
}Config lookup order:
-config <path>TFDL_CONFIG./tfdl.json(if present)
Environment variable overrides:
TFDL_PORTTFDL_BINDTFDL_ROOTTFDL_AUTH_ENABLEDTFDL_AUTH_USERTFDL_AUTH_PASS
Priority: Flags > Environment > Config file > Defaults
- Dynamic
/t/<alias>/redirects from the registry /healthzendpoint (no auth)- Optional Basic Auth (disabled by default)
- Blocks direct access to
.gitpaths when serving project root - Request logging and graceful shutdown (
SIGINT/SIGTERM)
assets/css/styles.cssimportsassets/css/framework.cssassets/css/skins/canva-dark.cssprovides the default skinassets/css/user.cssis loaded last for local tweaks/branding
To use the older terminal-style look on a page, add theme-terminal to that
page's <body> class.