{"slug": "a-dash-of-dev-to-my-blog-stats-now-live-in-the-terminal", "title": "A Dash of dev.to: My Blog Stats Now Live in the Terminal", "summary": "A developer built a terminal dashboard to display dev.to blog statistics using a Go program and the archived devdash project. The tool fetches article data via the dev.to API and renders it in a configurable terminal interface, allowing quick access to metrics like views, reactions, and comments.", "body_md": "*Hello, I'm Maneshwar. I'm building git-lrc, a Micro AI code reviewer that runs on every commit. It is free and source-available on Github. Star git-lrc to help devs discover the project. Do give it a try and share your feedback.*\n\nI check my dev.to stats more often than I would ever admit in a job interview.\n\nReactions, views, comments, the little numbers that go up, and the ones that stubbornly refuse to.\n\nNormally that ritual means opening a browser, clicking into the dashboard, and squinting at one article at a time like I'm reading tea leaves.\n\nI wanted something calmer.\n\nOne terminal window.\n\nMy top articles ranked by likes, by views, and by comments, all on screen at once, quietly refreshing itself while I pretend to do real work.\n\nSo I built it in an afternoon.\n\nIt took a tiny Go program, one wonderful archived project doing the heavy lifting, and two bugs I absolutely did not order but got served anyway.\n\nLet me walk you through it, bugs and all.\n\nThe plan had three moving parts.\n\nOne, dev.to already hands you your own data.\n\nThere is an endpoint, `GET /api/articles/me`\n\n, you send your API key in an `api-key`\n\nheader, and you get back every article you have published with the fields that matter already counted for you: `positive_reactions_count`\n\n, `page_views_count`\n\n, and `comments_count`\n\n.\n\nNo scraping, no HTML parsing, no crying.\n\nYou can generate a key at your dev.to settings under Extensions.\n\nTwo, I did not want to build a whole TUI from scratch.\n\nGrids, colors, borders, keyboard handling, refresh loops. Life is short xD\n\nThree, therefore, I needed something that already draws pretty terminal dashboards and would happily show my numbers if I fed it nicely.\n\nThat third thing exists, and it is called devdash.\n\n{ % embed [https://github.com/Phantas0s/devdash](https://github.com/Phantas0s/devdash) %}\n\n[devdash](https://github.com/Phantas0s/devdash) is a highly configurable terminal dashboard by Matthieu Cneude, better known as Phantas0s.\n\nIt has widgets for GitHub, Google Analytics, Google Search Console, Travis, and more, and the entire layout is driven by a single YAML file.\n\nRows, columns, t-shirt sizes, colors, all declarative.\n\nIt is a genuinely lovely piece of Go.\n\nTwo small catches. It has been archived since 2023. And it has precisely zero concept of what dev.to is.\n\nNow, I could have forked it, added a proper Forem service, wired up structs, written tests, and opened a pull request into a repo that is politely closed for business.\n\nInstead I found the lazy door, and it was already unlocked.\n\ndevdash has a widget called `lh.table`\n\n, the localhost table.\n\nYou hand it a shell command, it runs that command, and it renders whatever the command prints as a bordered table.\n\nIt splits each line of output on whitespace and slots the pieces into columns. That is the whole contract.\n\nSo devdash does not need to know about dev.to.\n\nIt just needs a command that prints rows. I can be that command.\n\nIf Matthieu ever reads this: thank you for building a tool flexible enough to be abused this gracefully.\n\nGo bother [Matthieu on X](https://x.com/Cneude_Matthieu) and tell him his archived project is still out here pulling shifts.\n\nHere is the shape of the whole thing.\n\nThe little Go binary in the middle is the only thing I actually had to write.\n\nI called it `devto-stats`\n\n.\n\nIt fetches all my articles (paginating 100 at a time until dev.to runs out), keeps only the published ones, sorts them by whichever metric devdash asks for, and prints clean rows.\n\n```\nreq.Header.Set(\"api-key\", apiKey)\nresp, _ := client.Do(req)\n// GET https://dev.to/api/articles/me?per_page=100&page=N\n```\n\nAnd the config just points three table widgets at three flavors of that command.\n\n```\n- name: lh.table\n  options:\n    title: \" MOST VIEWED \"\n    command: \"./bin/devto-stats -mode=table -sort=views -limit=10\"\n    headers: \"#,Article,Views\"\n    border_color: green\n```\n\nThree of those blocks, colored red, green, and yellow, sitting side by side. In theory, done.\n\nIn theory.\n\nI turned it on. Overview strip populated. Most Liked, glorious. Most Commented, present.\n\nMost Viewed, a bright red ERROR box.\n\nThe command worked perfectly by hand.\n\nIt only failed inside devdash.\n\nThe clue was in how devdash refreshes: it fires every widget concurrently, each in its own goroutine, all at the same instant.\n\nFour widgets meant four copies of `devto-stats`\n\nsprinting at the dev.to API at once, elbows out. dev.to did the sensible thing and replied `429 Too Many Requests`\n\n.\n\nOne of the four always lost the race, usually Most Viewed.\n\nI had built a very small, very polite denial of service attack against myself.\n\nThe fix is the boring, correct one: on a 429, wait and retry, with backoff plus jitter.\n\n```\nif resp.StatusCode == http.StatusTooManyRequests {\n    backoff := time.Duration(attempt-1) * 700 * time.Millisecond\n    jitter := time.Duration(rand.Intn(500)) * time.Millisecond\n    time.Sleep(backoff + jitter)\n    continue // try this page again\n}\n```\n\nThe jitter is the important part. Without it, all four back off by the same amount and collide again, like four people apologizing and stepping the same way in a hallway.\n\nWith a random offset, they spread out on their own.\n\nZero errors after that.\n\nMost Viewed finally rendered. And it rendered wrong.\n\nThe first row looked fine, then every row below slid one column right.\n\nTitles in the numbers column, numbers nowhere.\n\nI recognized the article where it started.\n\nMy top post is titled \"Good Bye CRUD APIs, Hello Sync\".\n\nLook at the punctuation.\n\nHere's what devdash does under the hood: it splits each line on whitespace to get cells, joins those cells back together with commas, then splits the whole batch on commas again to chunk it into rows of N columns.\n\nA comma inside a title is indistinguishable from a comma devdash added on purpose.\n\nOne title becomes two cells, the row has four pieces instead of three, and because the chunking is global, every row after it is shifted forever.\n\nThe real fix belongs upstream, in a repo that isn't taking visitors.\n\nSo I fixed it on my side, where I control the output.\n\nMy binary already slugifies titles to survive the whitespace split.\n\nI just taught it to evict commas too.\n\n```\ns := strings.Join(strings.Fields(title), \"-\")\ns = strings.ReplaceAll(s, \",\", \"\") // devdash re-splits the table on commas\n```\n\nOne line. The comma-tose table woke right up.\n\nHere is the raw feed one panel runs on, straight out of the binary, real numbers from my actual account:\n\ndevdash takes three of those feeds and frames them into colored, bordered, self refreshing tables sitting shoulder to shoulder: Most Liked in red, Most Viewed in green, Most Commented in yellow, with a summary strip across the top.\n\n`Ctrl+R`\n\nforces a refresh, `Ctrl+C`\n\nquits, and left to its own devices it repaints itself every five minutes.\n\n444 articles, all of them accounted for, no browser, no clicking, just a quiet terminal telling me the truth about which posts people actually read.\n\n**The best integration is often no integration.** devdash never learned about dev.to.\n\nI made dev.to speak devdash's language instead, and a tool that stopped being maintained in 2023 rendered 2026 data without a single change to its source.\n\nThe whole thing, Go helper, YAML, and Makefile, is here: [lovestaco/devto_devdash](https://github.com/lovestaco/devto_devdash).\n\nBring your own API key.\n\nAnd real gratitude to Matthieu Cneude for devdash.\n\nSometimes the best tool for the job is one somebody stopped working on years ago, sitting there quietly, still perfectly happy to dash off one more dashboard.\n\nAI agents write code fast. They also silently remove logic, change behavior, and introduce bugs — without telling you. You often find out in production.\n\ngit-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.\n\nAny feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.\n\n⭐ Star it on GitHub:\n\n| [🇩🇰 Dansk](https://github.com/HexmosTech/git-lrc/readme/README.da.md) | [🇪🇸 Español](https://github.com/HexmosTech/git-lrc/readme/README.es.md) | [🇮🇷 Farsi](https://github.com/HexmosTech/git-lrc/readme/README.fa.md) | [🇫🇮 Suomi](https://github.com/HexmosTech/git-lrc/readme/README.fi.md) | [🇯🇵 日本語](https://github.com/HexmosTech/git-lrc/readme/README.ja.md) | [🇳🇴 Norsk](https://github.com/HexmosTech/git-lrc/readme/README.nn.md) | [🇵🇹 Português](https://github.com/HexmosTech/git-lrc/readme/README.pt.md) | [🇷🇺 Русский](https://github.com/HexmosTech/git-lrc/readme/README.ru.md) | [🇦🇱 Shqip](https://github.com/HexmosTech/git-lrc/readme/README.sq.md) | [🇨🇳 中文](https://github.com/HexmosTech/git-lrc/readme/README.zh.md) | [🇮🇳 हिन्दी](https://github.com/HexmosTech/git-lrc/readme/README.hi.md) |\n\nGenAI today is a **race car without brakes**. It accelerates fast -- you describe something, and large blocks of code appear instantly. But AI agents *silently break things*: they remove logic, relax constraints, introduce expensive cloud calls, leak credentials, and change behavior -- without telling you. You often find out in production.\n\n** git-lrc is your braking system.** It hooks into\n\n`git commit`\n\nand runs an AI review on every diff In short, git-lrc helps **Prevent Outages, Breaches, and Technical Debt Before They Happen**\n\n**At a glance:** [10 risk categories](https://github.com/HexmosTech/git-lrc#what-git-lrc-checks-for) · [100+ failure patterns tracked](https://github.com/HexmosTech/git-lrc#what-git-lrc-checks-for) · every commit…", "url": "https://wpnews.pro/news/a-dash-of-dev-to-my-blog-stats-now-live-in-the-terminal", "canonical_source": "https://dev.to/lovestaco/a-dash-of-devto-my-blog-stats-now-live-in-the-terminal-4l4e", "published_at": "2026-07-14 19:38:18+00:00", "updated_at": "2026-07-14 19:58:07.556611+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["Maneshwar", "dev.to", "devdash", "Matthieu Cneude", "Phantas0s", "GitHub", "Go"], "alternates": {"html": "https://wpnews.pro/news/a-dash-of-dev-to-my-blog-stats-now-live-in-the-terminal", "markdown": "https://wpnews.pro/news/a-dash-of-dev-to-my-blog-stats-now-live-in-the-terminal.md", "text": "https://wpnews.pro/news/a-dash-of-dev-to-my-blog-stats-now-live-in-the-terminal.txt", "jsonld": "https://wpnews.pro/news/a-dash-of-dev-to-my-blog-stats-now-live-in-the-terminal.jsonld"}}