Post

Jira Report — A Tiny Tool for People Who Don't Want to Learn JQL

A tiny Jira report tool that answers one question — what did the team work on in a given period? Pick boards, pick dates, get a table. JQL-free.

This post was written with Claude Code (Anthropic's claude-opus-4-6 model).

I built the whole thing end-to-end with my late-night pair-programming buddy Claude: architecture, Next.js edge routes, D1 schema, AES-256-GCM share encryption, UI components, and this blog post.

I built a small Jira report tool that answers one question: what did the team work on in a given period? You pick boards, pick dates, get a table. Nothing more.

JQL can already do this. But JQL has a learning curve, and most people on a team don’t have the time or interest to write queries. So I built a form.

Live: jira-report.pages.dev


Every sprint review, every weekly sync, every 1:1 — someone asks the same question.

“What did you work on this week?”

Or the manager version:

“What has the team been doing?”

Jira has the data. Every worklog, every assignee, every timestamp is sitting right there in the API. You can absolutely answer these questions with Jira. You just have to:

  1. Open the issue search
  2. Write a JQL query with the right date range, the right project, the right worklog author
  3. Hope you remembered the syntax for worklogDate vs worklogAuthor
  4. Group the results mentally because JQL doesn’t really group
  5. Open each issue to read worklog comments

Or you export to CSV and wrangle it in a spreadsheet. Or you install a paid plugin. Or you just… don’t bother.

That’s the gap I wanted to fill. Not because JQL is bad — it’s great — but because the barrier to entry is too high for a question that gets asked 10 times a week.

Two pages. That’s it.

Time Report — pick boards, pick a date range, get a table of team members and what issues they worked on. Each row shows the issue key, summary, and hours spent. Click a member to expand their issue list.

Weekly Comparison — compare multiple weeks side by side. Useful for “is the team speeding up or slowing down?” conversations.

No JQL. No fields to configure. No plugins to install. You enter your Jira domain, email, and API token once, and the app remembers. Everything happens in your browser — the credentials never leave your session unless you explicitly choose to share a report.

This one I’m proud of. You generate a report, click Share, get a link. The person you send it to opens the link and sees the same report — no credentials, no Jira account, nothing. Data refreshes when they open the link.

How it works:

  • Your Jira API token gets encrypted with AES-256-GCM and stored in Cloudflare D1
  • The share link is a random 16-byte ID (128 bits of entropy — unguessable)
  • When the viewer loads the link, the server decrypts your token, fetches fresh data from Jira, streams it back
  • You get a separate manage token (stored only in your browser) that lets you revoke the link anytime
  • Links auto-expire after 30 days

The encryption is bound to the share ID as additional authenticated data (AAD), so you can’t copy ciphertext between records. The master key is a Cloudflare secret. I never log decrypted tokens, never include them in responses, never touch them except to pass them to the Jira API for that one request.

Is it bulletproof? No. If someone compromises my Cloudflare account, they get encrypted blobs they can’t decrypt without the master key. If they get the master key too, game over. The same is true for every service that stores API tokens. I accept that trade-off because the alternative — no sharing at all — makes the tool significantly less useful.

I keep coming back to this because it’s the obvious counter-argument. Let me answer it properly.

JQL is powerful. Really powerful. For someone who uses Jira every day and enjoys the syntax, nothing I build will be better than a well-crafted query. That person should keep using JQL.

But most teammates I’ve worked with fall into one of these buckets:

  1. Never touched JQL. They click through the board UI, drag cards, log work, and that’s it. Asking them to “just write a query” is asking them to learn a new tool they don’t want.
  2. Touched JQL once, got burned. Wrote a query, got weird results, couldn’t figure out why. Gave up. Now they export to CSV.
  3. Know JQL well but don’t want to retype the same query every Friday. They bookmark it. But bookmarks break, date ranges go stale, and the colleague who asked “can you send me last week’s report?” gets left hanging.

The tool isn’t for case #3 — they’re fine. It’s for cases #1 and #2. It’s a form that runs the query for them. No syntax to memorize. No edge cases to trip over. Pick a board, pick a date, click generate.

  • Next.js 15 App Router on Cloudflare Pages with Edge runtime everywhere
  • Cloudflare D1 for share metadata (SQL is nice for this, KV wasn’t enough once I added view counts)
  • Web Crypto API for encryption — no dependencies, native to the edge runtime
  • Recharts for the weekly comparison chart
  • Tailwind CSS with a Rose primary color and dark mode
  • date-fns for date handling (anything but native Date)

Everything runs at the edge. No Node server, no background workers, no cron jobs. The free tier handles it without breaking a sweat.

One interesting constraint I hit earlier: Cloudflare Workers have a 50-subrequest limit per invocation on the free tier. My first version fetched worklogs issue-by-issue and blew past that limit for boards with many issues. I wrote about that in a separate post — short version: embed worklogs in the JQL search response instead of making separate API calls per issue, and you go from 50+ subrequests to 1.

Three things.

Build tools for your team, not for yourself. I use JQL. I can write the query for last week’s worklog report in 30 seconds. Building this tool was for everyone else — the designer who doesn’t want to learn Jira internals, the PM who needs a report for a stakeholder, the contractor who just wants to see what they did this week without logging into Jira at all. The hardest part wasn’t the code; it was remembering that not everyone thinks about work the way I do.

“Simple” is a feature. The whole app is three pages. I had to actively resist adding more. Every time I thought “I should add filtering / sorting / tagging / search”, I stopped and asked “who is this for?” Usually the answer was “me, and nobody has actually asked for this”. I deleted the feature from my plan. The result is a tool that loads instantly, does one thing, and doesn’t require a tutorial.

Claude Code made me ship this. I’ve had the idea for a year. Building all of it myself — auth, edge routes, D1 schema, streaming responses, UI for three pages, encryption for share links — would have taken weeks of evenings. With Claude Code it took a handful of sessions. I wrote the requirements, made the architectural calls, reviewed every diff. Claude wrote most of the code. That’s a very different workflow from “vibe coding” — it’s closer to pair programming with a partner who types very fast and never gets tired. The result is something I’d actually ship and use, not a half-finished weekend project.

If you use Jira and any of the pain points above resonate, give it a try.

Live: jira-report.pages.dev

You’ll need a Jira Cloud instance and an API token (generate one at id.atlassian.com). Everything runs client-side except for share links, which store an encrypted copy of your token on my Cloudflare D1 so shared viewers can refresh the data.

If you find a bug or want a feature, let me know.

That’s it. A small tool for a small problem. Sometimes that’s enough.