Writing Style Guide

Writing Style Guide

Derived from reading every post on the blog (10 posts, March–December 2023). This is not generic writing advice — every rule below is anchored in patterns that actually show up in the existing posts, with quotes where useful.

Tone & Voice

  • First person, direct, conversational. Posts are written as personal notes, not as documentation. Almost every post opens with “I” or describes a personal experience.
    • welcome: “Welcome, here I’ll be sharing my discoveries, studies, and experiences in the software industry.”
    • rinha-de-backend: “I participated in the Rinha de backend challenge and after some good hours of development… and my results were too far from I expected.”
    • got: “got is a CLI written in Go, created on top of the git CLI, to make my life easier by shortening some commands I use daily.”
  • Teach without lecturing. Explain what happened and what you learned. Avoid imperatives like “you should”. State things in your own experience (“for me”, “in my opinion”), then let the reader take what they want.
    • testcontainers: “Despite Testcontainers reducing the cost of integration tests and making them more reliable, it doesn’t remove the cost entirely.” (then: “in my opinion, the price is low compared to the benefit”)
  • Honest about mistakes. When something went wrong, say so plainly, including embarrassing ones. Self-deprecating humour is allowed.
    • rinha-de-backend: “I built the docker image to linux/arm64 instead of linux/amd64 🤦🤦🤦. I fixed the issue and ran the same tests afterward…”
    • tidy-first: “It’s not a 10/10 because the first section about actual tydings with practical examples felt a bit unnecessary.”
  • No hype, no marketing language. Comparisons are “10/10”, “8/10”, “excellent”, “super nice”, but never “game-changer”, “revolutionary”, “blazing fast”.

Sentence & Paragraph Length

  • Short paragraphs. Most paragraphs are 1–3 sentences. Long paragraphs (4+ sentences) are rare; when they appear they are explanations of a concept, not narration.
    • go-decimal-type is a model of brevity: 22 lines total, paragraphs of 1–2 sentences, two bullets.
  • Medium-length sentences. Not punchy one-worders, not academic prose. Average 12–22 words. Lists, code, and headings break up the flow heavily.
  • Allowed informalities: lowercase “i” occasionally, minor typos (“Importig”, “lazyness”, “challeges”, “insteresting”, “recive”, “laden”, “Apelido” — many posts contain typos). Don’t polish out the human touch but don’t intentionally add errors either; the blog has them because they’re real.

Opening Patterns

Three recurring openings:

  1. Lead with the artifact / outcome.
    • got: “got is a CLI written in Go, created on top of the git CLI, to make my life easier by shortening some commands I use daily.”
    • csv-import: “If you are using Go ad PostgreSQL, and need to performa a bulk import a CSV, it’s most likely you will find the COPY protocol is the feature that suits you better.”
  2. Lead with a story / personal scene.
    • rinha: “I participated in the Rinha de backend challenge and I was super excited… So I stayed up til later that night grabbed popcorn, and waited for the results. Well, I wish I hadn’t waited…”
    • tidy-first: “The book is clear, objective, and easy to read. Its simple explanations and examples…”
  3. Lead with a hook question or “Picture this”.
    • testcontainers: “Picture this, you have a critical and reasonably complicated piece of logic in your application that is handled in the database… So, what do you do?”

Avoid: “In this post, I will…”, “Today I’m going to talk about…”, “Recently, I…”

Closing Patterns

  • Invite the reader in (“What about you? How do you write integration tests, and what are your main challenges?” — testcontainers).
  • Project forward (“I’ll apply the lessons learned to my solution and hopefully get better results. Watch [repo] and see how it will evolve.” — rinha).
  • Sign off casually (“Till next time o/” — got).
  • TL;DR + link to repo for technical posts: “Checkout the repository with examples and details presented here.”

The post almost never ends with a summary “in conclusion” paragraph. If it does, it’s brief and contains forward-looking or personal commentary.

Headers & Structure

  • One H2 per major section, H3 for subsections. Headers are short, often a single word or phrase: “Context”, “How”, “Why”, “Final thoughts”, “What’s next?”.
    • got uses ### But... Why?, ### How, ### Ok, what about the logic in got?, ### Conclusion and what's next?. Questions and informal phrasings are welcome.
  • No deep header nesting. H4+ is rare and only used for inline sub-cases.
  • <!--more--> excerpt break appears in every post: above it is the lead image and the lede paragraph (1–2 paragraphs); below it is the full content. The lede is what shows on the index page.
  • TL;DR callout appears as a Markdown blockquote (> TL;DR: ...) right after the <!--more--> for most posts. Sometimes it includes the GitHub repo link.

Code Blocks

  • Always fenced with a language tag (go, shell, sql). Code is real, runnable code from the project — never pseudocode.
  • Code is introduced, not dropped. A short sentence frames the snippet, then the snippet, then commentary. (See got’s #### Install / #### Booststraping your CLI pattern.)
  • Real CLI output is included verbatim for steps where seeing the output matters (testcontainers prints the full go test -v output).
  • One code block per concept. Don’t bury multiple ideas in one snippet.

Callouts, Quotes, Asides

  • Markdown blockquotes (>) are used for:
    • The TL;DR.
    • Quotes from external sources (book descriptions, xkcd captions).
    • Cautionary or sidebar notes: got has > Speaking on zsh... if you use it with the go plugin, you will have a conflict with the alias got for go test.
  • Italic emphasis (_..._) is used for meta-notes and personal asides: “The snippet below is part of the root.go”, “You can read more about the meaning of each metric on…”.
  • No “tip boxes” or styled aside components. Everything is plain Markdown.

Images & Visuals

  • Every post leads with a single image or video inside a <figure class="aligncenter">.
    • Image path uses Jekyll’s absolute_url filter: <img src="https://fsilva.me/images/foo.webp" alt="..." />.
    • Alt text is plain English describing the image.
  • Captions via <figcaption> when the image needs context, often with credit.
  • In-line figures appear where they aid the narrative (memes, result screenshots, “before/after” comparisons in rinha-de-backend).
  • Image content leans fun / personal: Gophers, xkcd strips, memes, screenshots of dashboards — not stock photography or diagrams.
  • External links open in a new tab with {:target="\_blank"}. Every external link uses this pattern.
    • Example: [got](https://github.com/flavio1110/got){:target="\_blank"}.
  • Internal / cross-references to personal projects always point to the GitHub repo with a short framing sentence: “Checkout the repository with examples and details presented here.”
  • Code identifiers are linked to their official docs (pgx.CopyFrom, pgx.CopyFromRows, Effective Go).
  • Names of tools / people get inline links to homepages or Twitter on first mention.

Length Conventions per Post Type

  • Short (15–60 lines): Quick gotchas or simple announcements (go-decimal-type = 22 lines, go-resources = 67 lines, tidy-first = 53 lines, frontendmentor = 47 lines, youtube-suggestions = 62 lines).
  • Medium (100–160 lines): Tutorials with one or two code blocks (csv-import = 135, rinha-de-backend = 132, got = 191 — slightly longer).
  • Long (200–310 lines): Deep dives with several code blocks and step-by-step structure (testcontainers = 307 lines).

A two-paragraph “short note” is acceptable when the message is genuinely small (see go-decimal-type).

Tags & Frontmatter

The Jekyll frontmatter schema (consistent across all 10 posts):

1
2
3
4
5
6
7
8
9
10
---
layout: post
title: "EMOJI Short descriptive title"     # Title starts with a single emoji
date: YYYY-MM-DD 14:00:00 +0100            # Always 14:00 +0100 (CET), no exceptions
mood: speechless                           # mood: speechless | happy (sometimes omitted)
description: <one-sentence summary used by SEO/excerpt>
tags:
  - tag-one
  - tag-two
---

Title conventions:

  • Always leads with a single emoji that signals the topic (🐔 rooster fight, 🐉 dragon for “got”, 🔥 for hot takes, 📂 for file/data, 🧠 for learning, 🔢 for numbers, 🧹 for cleanup, 👋 for hello, 📺 for video).
  • Title is short — usually under 60 characters.
  • Titles are phrased conversationally, not as SEO headlines.

Tag conventions:

  • Lowercase, hyphenated where multi-word (gotchas, thougths — note the typo, don’t “correct” it; new posts should use existing tag names where possible).
  • Reused tags: go, programming, tools, learning, gotchas, thougths, postgresql, docker, database, tests.
  • 3–5 tags per post.

Mood:

  • Used in most posts. speechless for serious / technical / “wow this is interesting” content, happy for lighter / celebratory / list-style posts. The welcome post uses happy; tidy-first, got, rinha, csv-import, testcontainers, frontendmentor, go-decimal-type use speechless. Use sparingly; omit only if unsure.

Voice & Point of View

  • First person singular for personal narrative (“I participated”, “I built”).
  • First person plural / second person sparingly, when explaining (“we can now effortlessly run not only…”, “When studying HTML, CSS, and Javascript it’s hard to practice…”).
  • Never third-person about yourself. Never “the author” or “Flavio”.

How Lessons Are Framed

  • Lessons are observations from experience, not prescriptions. Often end with “What about you? … How do you…” to invite the reader’s perspective.
  • Lessons come at the end, in sections titled “Conclusion”, “Final thoughts”, “What’s next?”, “Ok, what about the logic in got?”, or woven into the body.
  • Failure is part of the lesson. rinha-de-backend has a whole section “What could I have done differently?” listing 5 bullet points of what went wrong — that’s the structural model for retrospective posts.

Emoji & Tone Markers

  • Sparse emoji usage: one or two per post, usually in the title. In-body emoji is rare, mostly used for self-deprecation (🤦🤦🤦, 😅, 💪).
  • No emoji in technical sections (code, headings, lists).
  • xkcd and meme references are welcome as flavour when they fit (got includes the xkcd “Automation” comic).

Anti-patterns to Avoid

  • ❌ Opening with “In this post, we will…”
  • ❌ Long-winded preambles before getting to the point
  • ❌ Stuffed “Conclusion” paragraphs restating the body
  • ❌ Generic SEO titles like “How to X: A Complete Guide”
  • ❌ Marketing words: “blazing fast”, “revolutionary”, “next-generation”
  • ❌ Bullet points where prose works better
  • ❌ Hiding which repositories are involved — always link the actual repo

Avoiding AI Tells

Posts on this blog are first-person notes, not LLM output. The patterns below are how readers (and reviewers) spot LLM-written text at a glance. If a draft contains more than a couple of these, rewrite it. The goal is not to banish every common construction — the goal is to make sure each sentence reads like something a person typed, not something a model statistically completed.

Punctuation

  • Em dashes (). The single biggest give-away. One per post is fine; three is a smell; five or more means the text was generated. Prefer commas, periods, colons, or parentheses. Use an em dash only when the parenthetical truly interrupts and cannot be rephrased cleanly. Most “punchy” em-dash usages can be rewritten as two sentences.
  • Curly quotes ("…", '…'). Use straight ASCII quotes ("…", '…'). Curly quotes are a ChatGPT default.
  • Trailing-negation clauses (“…, no guessing.”, “…, no wasted motion.”). Rewrite as a real clause. “The options come from the selected item, without forcing the user to guess.”
  • Negative parallelisms (“It’s not just X, it’s Y.”, “Not only… but also…”). Use sparingly. Most can be collapsed into a single positive sentence.

Word Choice

  • AI-vocabulary words. Avoid: crucial, delve, emphasizing, enduring, enhance, fostering, garner, highlight, interplay, intricate, landscape (abstract), pivotal, showcase, tapestry (abstract), testament, underscore (verb), valuable, vibrant, leverage, robust, seamless, holistic, dive (verb), navigate (figurative), realm, in today’s, in the world of.
  • Promotional adjectives. breathtaking, vibrant, stunning, groundbreaking (figurative), nestled, in the heart of, must-visit. None of these belong in a technical post.
  • Significance inflation. stands as, serves as, is a testament, marks a pivotal moment, reflects broader trends, a key turning point. Strip the puffery; state the fact.
  • Persuasive-authority tropes. the real question is, at its core, in reality, what really matters, fundamentally, the deeper issue. These phrases pretend to cut through noise; usually they just restate the obvious with extra ceremony. Cut them.
  • Signposting / announcements. Let’s dive in, let’s explore, let’s break this down, here’s what you need to know, without further ado. Just start the next paragraph.
  • Collaborative artifacts. I hope this helps, Of course!, Certainly!, Great question!, let me know if. These belong in chat replies, not blog posts.
  • Hedge stacks. could potentially possibly be argued that… might have some. Pick one hedge or none.

Sentence & Paragraph Shape

  • Rule of three. “Autonomous enough, deterministic enough, small enough.” “Detect, propose, persist.” These three-beat rhymes are an LLM favourite because the rhythm is statistically attractive. Allow them only when the three are genuinely the same kind of thing. Otherwise, break the third item into its own sentence or paragraph.
  • Tailing fragments. Ending a sentence with “and that’s what matters.”, “and the rest follows.”, “— full stop.” for emphasis. Use a real sentence.
  • Inline-header vertical lists. - **Speed:** Code generation is faster. - **Quality:** Output is cleaner. - **Adoption:** More teams use it. If the bolded label is just a topic and the sentence after it is the actual point, write prose: “Code generation is faster, output is cleaner, and adoption is growing.”
  • Fragmented headers. A heading followed by a one-line warm-up that restates the heading (“## Performance\n\nSpeed matters.\n\nWhen users hit a slow page, they leave.”). Cut the warm-up line.
  • Synonym cycling. AI substitutes synonyms to dodge its own repetition penalty. If “protagonist” / “main character” / “central figure” / “hero” all appear in three paragraphs, use “protagonist” each time or restructure.

Lists & Structure

  • Bullet points where prose works. Three short bullets that say one thing each are usually one paragraph.
  • Bullets that all start with the same word pattern (“The X is…”, “The X is…”, “The X is…”). Vary the sentence structure inside the bullets or fold them into prose.
  • Title Case in headings. Use sentence case (“The traps, in order”, not “The Traps, In Order”). Existing posts are already sentence case.
  • Decorative emoji in headings or bullets (🚀, 💡, ). Emojis are fine in the title; not inside the body.
  • False ranges. “From X to Y, from A to B” where X/Y/A/B are not on a real scale. Replace with the actual list.

Structure (Post-level)

  • Outline-like “Challenges and future prospects” section. LLM writing pads the end with a generic “challenges remain, but the future is bright” paragraph. If something is genuinely limiting, write it as a specific tradeoff with a name and a number. If not, cut it.
  • Generic positive conclusion. “The future looks bright.”, “Exciting times lie ahead.”, “A major step forward.” These are filler. Replace with the next concrete thing you plan to do, or end with a question to the reader.

Self-Check Before Publishing

Read the draft aloud. If any of the following happens, rewrite:

  1. You used more than one em dash in a paragraph.
  2. You used a three-beat rhythm where the third item was forced into the shape.
  3. A bullet list has more than three items and each item starts with the same word.
  4. The conclusion is a generic upbeat paragraph rather than a concrete next step or a question.
  5. A sentence uses crucial, pivotal, delve, showcase, leverage, robust, or seamless.

The existing posts on this blog are the reference for what “human voice” looks like. When in doubt, re-read rinha-de-backend and got and copy their rhythm: short paragraphs, varied sentence length, code that earns its place, lessons that come from a specific failure.

Style Checklist (per post)

  1. Frontmatter matches the schema above (emoji + short title, 14:00 +0100, mood, description, 3–5 tags).
  2. <!--more--> break is present.
  3. Opens with a <figure class="aligncenter"> and a relevant image (or video).
  4. First paragraph is short (1–3 sentences) and leads with the artifact / story / hook — not a generic intro.
  5. Every external link uses {:target="\_blank"}.
  6. Code blocks have a language tag and are introduced, not dropped.
  7. Voice is first-person and direct. No “we should”, no marketing tone. No AI tells (see Avoiding AI Tells above).
  8. Length matches the post type: short note → 1–2 paragraphs; tutorial → 100–200 lines; deep dive → 200–300 lines.
  9. Closes with forward-looking note, sign-off, or question to the reader — not a generic upbeat paragraph.
  10. No fabricated technical claims — link to real repos / docs.