Skip to content

nschneble/linklater

Repository files navigation

Linklater

License: CC0-1.0

Linklater is an Instapaper-inspired “read it later” app.

It’s both an homage to Richard Linklater and a ridiculously apt portmanteau.

Linklater

Who needs this?

Most curious adults come across dozens of interesting articles on any given day. Do they have time to read them all? Nope. Do they often forget about them? Totally.

Linklater allows these articles to be saved quickly and easily for later reading.

Features

As a user, you can:

  • Create an account with passwords, magic links, and/or Google SSO
  • Save links in-app or using the handy bookmarklet
  • Search and stumble!
  • Preview themes based on Richard Linklater's filmography
  • Toggle between light and dark mode
  • Generate API tokens for third-party integrations
  • Delete your account and burn it to the ground

Screenshots

Click on an image to open it full-size in a new browser tab:

Log In
Log In
Account Settings
Account Settings
Themes
Themes

Tech stack

Monorepo structure

It’s a majestic modular monorepo!

apps
├─ api/          # NestJS back-end
│  └─ README.md  # .env, modules, auth, jobs
│
├─ web/          # React + Vite front-end
│  └─ README.md  # .env, components, state, API, routes
│
├─ package.json  # root workspace + scripts
└─ README.md

Code health

Linklater's code quality is tracked with Desloppify, which scores each app independently across file health, code quality, duplication, security, and test health.

apps/api Desloppify scorecard
api
apps/web Desloppify scorecard
web

Bookmarklet

Linklater includes a one-click bookmarklet that saves the current page directly to your account.

To install, go to Settings → Bookmarklet and drag the Save to Linklater button to your bookmarks bar. Your auth token is embedded, so you can immediately click it on any page to save the link.

Local development

Prerequisites

Install dependencies

# cd /path/to/your/repo
npm install

Set environment variables

You'll need to set the database url, JWT secret, app url, and SMTP values on the back-end, and the API's base url on the front-end for Vite to access.

# cd /path/to/your/repo

# set DATABASE_URL, JWT_SECRET, APP_URL, SMTP_*
cp apps/api/.env.example apps/api/.env

# set VITE_API_BASE_URL
cp apps/web/.env.example apps/web/.env

Run database migrations

# cd /path/to/your/repo
bin/migrate
bin/migrate --help
bin/migrate --reset

Note: Use bin/migrate or npm run migrate instead of calling npx prisma migrate dev directly. Prisma 7's prisma-client generator requires a custom output path, so migrate dev does not automatically regenerate the client.

Start development server

# cd /path/to/your/repo
npm run dev

# -OR-

# start the development server TUI
bin/dev
bin/dev --help

Linklater uses concurrently to run NestJS on port 3000 and Vite on port 5173. Open https://localhost:5173 in your web browser and you're good to go!

dev

Linting, tests, and CI

Both the front and back-end use ESLint and Prettier. Vitest is used to test the front-end and Jest is used to test the back-end. GitHub Actions lint and test on pushes and PRs to main.

# cd /path/to/your/repo

npm run format
npm run lint
npm run test

# -OR-

# install, format, lint, test, and build in one TUI
bin/flintest
bin/flintest --help
bin/flintest --update

Visual regression tests

Visual + accessibility regression coverage is provided by Tuffgal:

  • Stories live in tuffgal/stories/
  • Committed baselines are in tuffgal/baselines/
# cd /path/to/your/repo

# one-time setup to create the test database + seed the test user
npm run test:ui:setup

# run the dev server in test mode + run every story against the baselines
npm run dev:test
npm run test:ui

# accept intentional UI changes as the new baseline
npm run test:ui:approve

Versioning

Create a new version in four easy steps!

  1. Run the version:bump script
  2. Update the new CHANGELOG section
  3. Create a version tag
  4. Create a new release and paste in the new CHANGELOG section
# cd /path/to/your/repo
npm run version:bump -- 0.3.0

# create a version tag
git commit -m "Bump version to 0.3.0"
git tag -a v0.3.0 -m "v0.3.0"
git push origin main
git push origin v0.3.0

Advanced

Remote access (LAN)

The development server TUI has a --remote option which allows Linklater to be discoverable by other devices on the same Wi-Fi network.

# cd /path/to/your/repo
bin/dev --remote

# Linklater is now available on https://linklater.local:5173
One-time setup for mobile devices

The teck stack uses mkcert for HTTPS. Mobile devices need to trust the mkcert root certificate authority, or the connection will be refused.

  1. Find the root CA on the computer where Linklater is running:
mkcert -CAROOT
# ~/Library/Application Support/mkcert
  1. AirDrop (iOS) or transfer (Android) rootCA.pem to your mobile device

  2. Install the certificate

    1. On iOS: Settings → General → VPN & Device Management. Then enable trust under Settings → General → About → Certificate Trust Settings.
    2. On Android: Settings → Security → Install from storage → CA certificate.
Set a friendly hostname (optional)

By default the LAN url uses your Mac's Bonjour hostname.

To get linklater.local instead:

sudo scutil --set LocalHostName linklater

This is a one-time system-level change and persists across reboots.

Remote access (public)

The development server TUI has a --public option which allows Linklater to be discoverable publicly using a Cloudflare TryCloudflare tunnel.

# cd /path/to/your/repo
bin/dev --public

# Linklater is now available on https://wildly-foxy-rice-pilaf.trycloudflare.com

Known limitations

  • Google SSO won't work; OAuth callback URLs are pinned to localhost
  • The bookmarklet generated on the Settings page won't work

About

Linklater is an Instapaper-inspired “read it later” app.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors