Skip to content
Back to skills

2565 Content Guidelines B4f2960a

ASecurity

General best practices for release post content, regardless of blog platform. These guidelines are based primarily on Tidyverse blog conventions, which provide a principled approach to announcing package updates.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
documentationpythonbashgitperformancedocumentation

Works with

  • cli

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2565-content-guidelines_b4f2960a --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2565 Content Guidelines B4f2960a?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2565 Content Guidelines B4f2960a
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2565-content-guidelines-b4f2960a/badge)](https://www.skillsdirectory.com/skills/tools-only-2565-content-guidelines-b4f2960a)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Content Guidelines for Release Posts

General best practices for release post content, regardless of blog platform. These guidelines are based primarily on Tidyverse blog conventions, which provide a principled approach to announcing package updates.

## Table of Contents

1. [Post Structure](#post-structure)
2. [Opening Style](#opening-style)
3. [Section Organization](#section-organization)
4. [Tone and Voice](#tone-and-voice)
5. [Code Examples](#code-examples)
6. [Acknowledgments](#acknowledgments)

## Post Structure

Standard structure for release posts:

```markdown
[Frontmatter - see formatting guides]

# Package Version

[Opening paragraph with package description]

[Installation instructions]

[Overview paragraph about the release]

## Major Feature 1
[Content...]

## Major Feature 2
[Content...]

## Minor improvements
[Bulleted list...]

## Acknowledgements
[Contributor list]
```

## Opening Style

### Opening Paragraph Pattern

Start with an announcement that establishes the package's core purpose:

> "We're [pleased/chuffed/stoked/thrilled/delighted/excited/...] to announce the release of [package] [version]. [Package] [core purpose description in one sentence]."

**Examples:**
- "We're chuffed to announce the release of testthat 3.3.0. testthat makes it easy to turn your existing informal tests into formal, automated tests"
- "We're pleased to announce the release of pkgdown 2.2.0. pkgdown is designed to make it quick and easy to build a beautiful and accessible website"
- "We're excited to announce the new Shiny extension for VS Code!"

**Vocabulary variations:**
- Choose an upbeat and random adjective with connotations of excitement.
- Be interesting and bold, but above all positive and fun.

### Installation Instructions

Follow the opening with installation instructions as a code block:

**R packages:**
```r
install.packages("packagename")
```

For multiple packages:
```r
install.packages(c("shiny", "bslib"))
```

**Python packages:**
```bash
pip install packagename
```

With extras:
```bash
pip install "packagename[extra]"
```

### Overview Paragraph

Brief overview of the release following installation:

- Link to full release notes when available
- Highlight focus areas: "This release focuses on [key themes]"
- Set expectations: "This is a [major/minor] release with [X main features]"
- Acknowledge breaking changes: "This release includes a number of new features... Some of these changes may require you to update your existing code"

## Section Organization

### Standard Section Hierarchy

Organize content in this order:

1. **Migration guide** (if breaking changes)
   - Put this first when there are breaking changes
   - Use clear before/after examples
   - Explain the rationale for changes

2. **Lifecycle changes** (if applicable but not breaking)
   - Soft deprecations
   - Deprecations
   - Defunct (removed) functions
   - Non-breaking behavioral changes

3. **Major new features** (primary content)
   - One section per major feature or theme
   - Use descriptive headings
   - Lead with what the feature does and why it matters
   - Include examples

4. **Minor improvements** or **Other new features**
   - Bulleted list of smaller enhancements
   - Brief explanations
   - Can group related items

5. **Acknowledgements** (always final)
   - Thank contributors
   - List all contributors with GitHub links

### Section Heading Style

- Use sentence case: "Lifecycle changes" not "Lifecycle Changes"
- Be descriptive: "Easier `in_parallel()`" not just "New feature"
- Include function names in backticks when relevant
- Make headings scannable and informative

### Content Organization Within Sections

**For migration guides:**
```markdown
## Migrating to vX.Y.Z

### Setting the app theme

Prior to vX.Y.Z, you could...

[Before example]

**With packagename vX.Y.Z,** you now need to...

[After example]

Read about [the feature](#feature) below to learn why this change was needed.
```

**For lifecycle changes:**
```markdown
## Lifecycle changes

* **Fully removed** after 5+ years of deprecation:
  * `function1()` - use `replacement1()` instead
  * `function2()` - use `replacement2()` instead

* **Newly deprecated** (soft-deprecation):
  * `function3()` is superseded by `function4()`
  * `function5()` is no longer recommended

* **Breaking changes**:
  * Brief description of the change and impact
```

**For feature sections:**
- Lead with a clear description of what the feature does
- Provide context on why it's useful or what problem it solves
- Include code examples showing usage
- Explain configuration options if relevant
- Link to relevant documentation

### Deep Dives on Features

Don't just list features from NEWS—research them and provide comprehensive explanations:

**Transform NEWS bullets into complete sections:**

1. **Research the feature**:
   - Read function documentation
   - Check related PRs and issues for context
   - Understand the motivation and use cases

2. **Add complete code examples**:
   - Show realistic usage, not just function signatures
   - Include comments explaining what's happening
   - Demonstrate the full workflow, not just isolated calls

3. **Explain the context**:
   - Why was this feature added?
   - What problem does it solve?
   - What are the practical use cases?
   - How does it fit into typical workflows?

4. **Show use cases and applications**:
   - Provide examples of when users would need this
   - Explain different configuration options
   - Show how features work together

**Example transformation:**

❌ **NEWS bullet approach:**
```markdown
## Bookmarking
- Added `chat_restore()` for bookmarking support (#82)
```

✅ **Deep dive approach:**
```markdown
### Bookmarking support

shinychat now supports Shiny's bookmarking feature for saving and restoring chat sessions.
The new `chat_restore()` function saves the chat client state and restores the message history:

[Complete code example showing actual usage]

By default, `chat_restore()` automatically updates the bookmark when users submit messages
and when the LLM completes its response. This means users can refresh the page or share a
URL and pick up right where they left off.

For apps with large chat histories, you can use `enableBookmarking = "server"` to store
state server-side without URL size limitations.
```

**Research sources:**
- Use `r-btw` tools to read R function documentation
- Read GitHub PRs/issues linked in NEWS
- Check package vignettes and articles
- Look at example apps in the repository

**For improvements:**
```markdown
## Minor improvements

* Brief description of improvement with function name in backticks
* Another improvement with relevant technical details
* Performance gains quantified when possible (e.g., "2x faster")
```

## Tone and Voice

### Writing Style

- **Conversational but professional**: "We're excited to announce" rather than "It is announced"
- **Inclusive**: Use "we" and "you" rather than passive voice
- **Enthusiastic but authentic**: Avoid over-the-top marketing language
- **Technical precision**: Use exact function names, parameter names, and technical terms
- **Focus on benefits**: Explain the "why" not just the "what"

### Avoiding Marketing Speak

Release posts should be friendly and instructional, not advertising. Watch for and remove:

**Superlatives and promotional adjectives:**
- ❌ "powerful set of features", "rich, interactive displays", "beautiful interface"
- ✅ "set of features", "interactive displays", "interface"

**Exaggerated benefit claims:**
- ❌ "handles all the complexity of persisting state"
- ✅ "saves the chat client state and restores the message history"

**Generic enthusiasm:**
- ❌ "opens up exciting possibilities for building transparent, user-friendly AI applications"
- ✅ Direct description of what the feature does

**Over-hyped capability statements:**
- ❌ "give you fine-grained control over every aspect"
- ✅ "lets you control the chat interface"

**Tone review checklist:**
- [ ] Remove words like "powerful", "robust", "seamless", "elegant", "revolutionary"
- [ ] Replace "makes it easy to" with direct descriptions of functionality
- [ ] Prefer descriptive statements focusing on what the function does
- [ ] Avoid overuse of phrases that sound like product marketing ("best-in-class", "production-ready")


### Common Phrases

- "We're [emotion] to announce..."
- "A big thank you to all the folks who helped make this release happen"
- "You can see a full list of changes in the release notes"
- "This makes it easier to..."
- "We've improved..."
- "This release focuses on..."
- "Prior to vX.Y.Z, you had to..."
- "With this release, you can now..."

### Technical Voice

- Use backticks for all code elements: `` `function()` ``, `` `argument` ``, `` `"value"` ``
- Link to relevant documentation when helpful
- Be specific about behavior: "returns `NULL`" not "returns nothing"
- Explain technical decisions when they impact users
- Acknowledge tradeoffs when present

## Code Examples

### Explain Concepts Before Code

For features that introduce new or unfamiliar concepts, explain the concept first before showing code:

**Pattern: Concept → How it works → Why it matters → Code**

1. **What is the feature/concept?** (1-2 sentences)
2. **How does it work?** (Especially non-obvious aspects)
3. **Why does it matter?** (Practical implications)
4. **Show the code** (With examples)

**Key principles:**
- Assume readers may not be familiar with the concept
- Explain non-obvious aspects clearly
- Connect concepts to practical outcomes
- Use plain language before technical language

### Inline Code

- Function names: `` `map_chr()` ``
- Arguments: `` `na.rm = TRUE` ``
- Values: `` `NULL` ``, `` `TRUE` ``, `` `"string"` ``
- File paths: `` `app.py` ``

### Code Block Principles

- Use realistic but simple examples
- Include expected output when relevant
- Show error messages for examples of better error handling
- Format multi-line function calls with proper indentation
- Add comments for clarity when needed: `# This does X`
- Keep examples focused on the feature being demonstrated

### Before/After Examples

When showing improvements, use clear before/after structure:

```markdown
Previously, you had to write:

[Code block showing old approach]

Now you can write:

[Code block showing new approach]
```

Or for migration guides:

```markdown
**Before:**

[Old code]

**After:**

[New code]
```

## Acknowledgments

### When to Include

- **Always include** for package releases with external contributors
- Optional for internal tooling announcements
- Include at the end as the final section

### Section Format

```markdown
## Acknowledgements

A big thank you to all [the folks/everyone] who [helped make this release happen/contributed to this release]:

[@username1](https://github.com/username1), [@username2](https://github.com/username2), ...
```

### Fetching Contributors

Use `usethis::use_tidy_thanks()` in R:

```r
# From last release to current
usethis::use_tidy_thanks("owner/repo")

# From specific tag/SHA
usethis::use_tidy_thanks("owner/repo", from = "v1.0.0")
```

This generates properly formatted markdown for the contributor list that can be included verbatim.

## Transforming NEWS to Blog Content

When converting NEWS.md entries to blog post format:

1. **Expand context**: Technical bullets become paragraphs explaining why changes matter
2. **Add examples**: Include code demonstrating new features or changes
3. **Group thematically**: Combine scattered NEWS items into coherent sections
4. **Use conversational tone**: Transform terse bullets into readable prose
5. **Link proactively**: Add links to relevant documentation and resources
6. **Focus on user impact**: Explain how changes affect typical usage
7. **Highlight breaking changes**: Make migration paths clear and prominent

## Release Notes Link

Always include a link to full release notes:

```markdown
You can see a full list of changes in the [release notes](url).
```

This allows readers to find exhaustive details while keeping the blog post focused and readable.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…