Skip to content

ngrok/calgrok

Repository files navigation

calgrok

A fast content calendar that runs live on top of Linear.

We plan a lot of content at ngrok, and our issues already live in Linear with due dates, labels, and assignees. What we didn't have was a calendar that felt good to use: the tool we'd been living in was slow and regularly froze the browser tab. calgrok is the rebuild. It reads everything straight from the Linear API, shows your content issues on a month grid by their due date, and lets you reschedule with a drag or a click. It stores nothing of its own.

Built for how ngrok's GTM and Content teams work, but configurable enough to run against another Linear workspace.

What it does

  • Shows Linear issues on a month calendar, placed by due date (which we treat as the publish date).
  • Drag an issue to another day to reschedule it, with the change saved to Linear optimistically (it moves instantly and rolls back if Linear says no).
  • Opens any issue in a modal to read the description and edit its due date or tags, including clearing the date to drop it off the calendar.
  • Discovers teams from Linear after login, filters by explicit team selection and label, and remembers view options (show weekends, completed, and sub-tasks) between visits.

How it works

calgrok is a React Router app that talks to Linear over OAuth. The token exchange and every Linear request happen on the server, so your access token lives in a signed, httpOnly cookie and never reaches the browser. There's no database: the server is a thin proxy in front of Linear, and the browser caches what it fetches for the session with TanStack Query. The UI is built with mantle, ngrok's design system.

Run your own

You'll need your own Linear OAuth app and a Linear workspace to point it at.

  1. Create an OAuth app at linear.app/settings/api/applications/new. Add http://localhost:3000/auth/linear/callback as a redirect URL (add your deployed URL's callback too, once you have one), and request the read and write scopes.
  2. Copy .env.example to .env and fill in LINEAR_CLIENT_ID, LINEAR_CLIENT_SECRET, LINEAR_REDIRECT_URI, and a SESSION_SECRET. Optionally set LINEAR_LABEL_NAMESPACE if you want to scope the calendar to a label namespace such as con/.
  3. Install and run:
    pnpm install
    pnpm dev          # http://localhost:3000
  4. To deploy, build the container and supply the same environment variables at runtime:
    docker build -t calgrok .
    docker run --rm -p 3000:3000 --env-file .env calgrok
    Serve it over HTTPS (the session cookie is Secure in production) and make sure the deployed callback URL is registered on your Linear OAuth app.

Adapt it to your workspace

calgrok discovers Linear teams after login. Select the teams you want in the UI; that selection is stored in your browser and no issues are fetched until at least one team has been selected.

By default, LINEAR_LABEL_NAMESPACE is blank, so the calendar shows dated issues from the selected teams and labels are optional filters. If you set LINEAR_LABEL_NAMESPACE=con/, only labels with that prefix are offered, the prefix is stripped in the UI, and unfiltered calendar views are scoped to issues with one of those labels.

Repo layout

.
├── app/
│   ├── routes/        Pages, the OAuth flow, and the BFF API routes that proxy Linear.
│   ├── features/
│   │   └── calendar/  The month grid, issue cards, filters, modal, and data hooks.
│   └── lib/           Server-side env, session, and Linear client helpers.
├── Dockerfile         Multi-stage production build.
└── PLAN.md            The design and the milestone-by-milestone build log.

Heads up

This is an internal ngrok tool we're sharing as-is. It's shaped around how we work and isn't a supported product, so we may not take issues or pull requests. Fork it and make it yours.

License

MIT

About

A fast content calendar that runs live on the Linear API

Resources

License

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages