DEV Community

Cover image for πŸ“ Dev.to Writers Community: One Command to Maintain Them All
Benoit COUETIL πŸ’« for Zenika

Posted on

πŸ“ Dev.to Writers Community: One Command to Maintain Them All

DEV Weekend Challenge: Community

This is a submission for the DEV Weekend Challenge: Community

The Community

The people writing technical articles right here on dev.to β€” the ones who keep a folder full of markdown files and occasionally wonder why they didn't just use the browser editor. Occasionally.

What I Built

A fork of devto-cli β€” a Node.js CLI that turns local markdown files into dev.to articles. The original tool by Yohan Lasorsa handles article creation, push to dev.to via the API, stats, GitHub-hosted images with automatic URL rewriting, and a GitHub Action for automated publishing.

I just kept running into small things it didn't cover, so I forked it and added a bunch of features. Here's what came out.

Demo

Content enrichment

Diagrams as code with Kroki

Write a diagram in your markdown:

<!-- diagram-name: shell-runner-well-sized-before-optimization -->
'''mermaid
%%{init: {'theme':'forest'}}%%
gantt
    title Shell Executor - Well-Sized Server (Before Extreme Optimization)
    dateFormat X
    axisFormat %s
    section Waiting
    Sufficient capacity                    :active, wait, 0, 1s
    section Server
    Resource allocation                    :active, prep, after wait, 1s
    section OS
    Native system (no container)           :active, env, after prep, 1s
    section Source Code
    Git fetch (local reuse)                :active, git, after env, 2s
    section Cache
    Restore (local filesystem)             :active, cache, after git, 2s
    section Artifacts
    Download artifacts                     :done, art, after cache, 3s
    section Execution
    Scripts                                :done, exec, after art, 10s
    section Termination
    Upload cache (local)                   :active, save1, after exec, 1s
    Upload artifacts (GitLab network)      :done, save2, after save1, 4s
'''
Enter fullscreen mode Exit fullscreen mode

Run:

dev diaggen my-article.md
Enter fullscreen mode Exit fullscreen mode

Diagram

The CLI sends the block to Kroki, gets back an image, and saves it locally. After committing the image to your assets repo, dev push replaces the code block with an image link pointing to GitHub β€” dev.to never sees the mermaid source. But your local source is preserved, letting you fix the diagram when needed. Supports mermaid, PlantUML, BlockDiag, and many others.

See 13 diagrams generated this way in GitLab Runners: Which Topology for Fastest Job Execution?

Automatic table of contents

Add two markers anywhere in your article:

<!-- TOC start -->
<!-- TOC end -->
Enter fullscreen mode Exit fullscreen mode

Then:

dev push --update-toc my-article.md
Enter fullscreen mode Exit fullscreen mode

The CLI scans headings and generates anchored links between the markers. The current article uses it.

ANSI-styled terminal output

Choosing colors in a displayed log is a must. The CLI converts a simple pseudo-ANSI syntax into styled HTML blocks.

In your markdown, use {{TAG}} to start a color. The {{/}} closing tag is optional β€” without it, the color continues until the next tag or end of block. This means multiline content stays colored naturally:

'''ansi
{{RED}}The quick brown fox{{BOLD_RED}} jumps over the lazy dog
{{GREEN}}The quick brown fox{{BOLD_GREEN}} jumps over the lazy dog
{{YELLOW}}The quick brown fox{{BOLD_YELLOW}} jumps over the lazy dog
{{ORANGE}}The quick brown fox{{BOLD_ORANGE}} jumps over the lazy dog
{{BLUE}}The quick brown fox
{{BOLD_BLUE}}jumps over the lazy dog
{{MAGENTA}}The quick brown fox{{BOLD_MAGENTA}} jumps over the lazy dog
{{CYAN}}The quick brown fox{{BOLD_CYAN}} jumps over the lazy dog
{{WHITE}}The quick brown fox{{BOLD_WHITE}} jumps over the lazy dog
{{GRAY}}The quick brown fox{{BOLD_GRAY}} jumps over the lazy dog
{{BG_RED}}The quick brown fox{{/}} jumps over the lazy dog
{{BG_GREEN}}The quick brown fox{{BG_YELLOW}} jumps over the lazy dog
{{BG_ORANGE}}The quick brown fox
jumps over the lazy dog
{{BG_BLUE}}The quick brown fox{{BG_MAGENTA}} jumps over the lazy dog
{{BG_CYAN}}The quick brown fox{{BG_WHITE}} jumps over the lazy dog
{{BG_GRAY}}The quick brown fox{{/}} jumps over the lazy dog
'''
Enter fullscreen mode Exit fullscreen mode

After dev push, this renders as a properly colored terminal block on dev.to β€” 9 base colors Γ— 3 variants (plain, bold, background). No closing tag needed: colors flow until the next tag, even across lines. All colors are overridable via .env variables (ANSI_RED=#ff6161, etc.).

The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox
jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox
jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog

illustration description

Bulk operations

Run one command, affect all your articles at once.

A shared footer file (e.g. "Further reading" links) kept in sync across all articles. Update the footer file once, then push all β€” the CLI finds the # Further reading marker in each article and replaces everything below it with the shared footer content:

dev push --update-toc "*.md"
Enter fullscreen mode Exit fullscreen mode

Smart file renaming

When an article title changes, the filename should follow:

dev rename "*.md"
Enter fullscreen mode Exit fullscreen mode
🦊 GitLab CI: A Battle-Tested Mono-Repo CI/CD Architecture
  GITLAB_mono-repo-architecture.md β†’ GITLAB_ci-battle-tested-mono-repo-ci-cd-architecture.md

πŸ” Every Developer Should Review Code β€” Not Just Seniors
  MISC_every-developer-should-review-code.md β†’ MISC_every-developer-review-code-seniors.md
Enter fullscreen mode Exit fullscreen mode

Strips emoji, filters 80+ English stop words (a, the, and, how…), keeps the first 5 significant words, preserves the date/category prefix.

Article badges generation

Generate visual badges for a GitHub profile README:

dev badges --jpg "*.md"
Enter fullscreen mode Exit fullscreen mode

Each badge overlays the article's cover image with its title, publication date, view count, and reading time. Articles are auto-grouped by category (extracted from filename prefix) and sorted by date within each group.

The most viewed articles get golden stars ⭐ β€” popularity is measured relative to the 2nd most viewed article (to avoid one viral post skewing everything). β‰₯90% of that reference = 3 stars, β‰₯50% = 2, β‰₯25% = 1. Stars and stats refresh on every run.

Produces a _ARTICLES.md file with badge images linking to each article. Here's my GitLab section:

🦊 GitLab CI: Achieving 3-Second Jobs on Million-Line Codebases 🦊 GitLab Runners: Which Topology for Fastest Job Execution?
πŸ”€ Efficient Git Workflow for Web Apps: Advancing Progressively from Scratch to Thriving πŸ”€πŸ¦Š GitLab: Forget GitKraken, Here are the Only Git Commands You Need
🦊 GitLab: A Python Script Displaying Latest Pipelines in a Group's Projects 🦊 GitLab: A Python Script Calculating DORA Metrics
🦊 GitLab CI: Deploy a Majestic Single Server Runner on AWS 🦊 GitLab CI: The Majestic Single Server Runner
🦊 GitLab CI YAML Modifications: Tackling the Feedback Loop Problem 🦊 GitLab CI Optimization: 15+ Tips for Faster Pipelines
🦊 GitLab CI: 10+ Best Practices to Avoid Widespread Anti-Patterns 🦊 GitLab Pages per Branch: The No-Compromise Hack to Serve Preview Pages
🦊 GitLab CI Jobs Attributes Sorter: A Python Script for Consistent YAML Files 🦊 GitLab Runners Topologies: Pros and Cons

Embed the file in a pinned article and all your articles become browsable from one place. Badges stay up to date with every dev badges run.

Broken link checking

Before publishing:

dev checklinks my-article.md
Enter fullscreen mode Exit fullscreen mode

Catches dead URLs before readers do. Smart enough to treat HTTP 403/429 as "probably fine" (bot blocking, not a dead link). Also validates cover image and canonical URL from front matter. Works on all articles at once with dev checklinks "*.md".

Environment

Configure once, forget about it.

Organization publishing

One line in .env:

DEVTO_ORG=zenika
Enter fullscreen mode Exit fullscreen mode

The CLI adds organization: zenika to the front matter and resolves the org ID automatically on push.

Proxy support for corporate environments

export HTTPS_PROXY=http://proxy.company.com:8080
dev push
Enter fullscreen mode Exit fullscreen mode

All API calls, Kroki requests, and link checks go through the proxy. Self-signed certificates handled too.

Code

github.com/bcouetil/devto-cli

How I Built It

This is a TypeScript / Node.js CLI, forked from sinedied/devto-cli. Each feature was added incrementally β€” proxy support first, then Kroki diagrams, TOC generation, organization publishing, footer management, link checking, file renaming, ANSI blocks, and finally badge generation.

This fork started as a one-line proxy fix and kept growing from there. Every feature was added because I needed it, not because it looked good on a feature list.

illustration description

Illustrations generated locally by Draw Things using Flux.1 [Schnell] model

Further reading

This article was enhanced with the assistance of an AI language model to ensure clarity and accuracy in the content, as English is not my native language.

Top comments (0)