Quickstart

The fastest path: add the packages, drop in the aliases, and point your assistant at the style. If your assistant has tool access, it can do all of this for you.

Let your AI set it up

Paste prompts/setup-prompt.md into your assistant in a new or existing repo. It detects the project (or scaffolds a Web API in an empty one), installs the packages it needs, writes GlobalUsings.cs, adds the compact-style rules to your CLAUDE.md / copilot-instructions.md, and builds to verify. It is safe to re-run; it only adds what is missing.

Claude Code users can skip the paste — the repo ships a skill at .claude/skills/dotnet/; just ask it to “set up Smoower.Minified in this project.”

Or install the Claude Code plugin

Smoower.Minified ships as a Claude Code plugin on Anthropic’s community marketplace. Add it once and the skill applies the compact style automatically — it even asks which compaction level to use before it generates:

/plugin marketplace add anthropics/claude-plugins-community
/plugin install smoower-minified@claude-community

It auto-invokes on any project that references the Smoower.Minified.* packages; call it explicitly with /smoower-minified:dotnet.

Or three small steps by hand

# 1 — add the packages (ASP.NET Core backend set)
dotnet add package Smoower.Minified.AspNetCore
dotnet add package Smoower.Minified.EFCore

# 2 — drop the usings + aliases into a GlobalUsings.cs
#     (copy from samples/Smoower.Minified.SampleApi/GlobalUsings.cs)

# 3 — point your AI at the style
#     Claude Code -> just ask it to "use Smoower.Minified"  (ships as a skill)
#     Copilot / Cursor / GPT -> paste prompts/system-prompt.md

That’s it — your next controller comes out compact. For the full package list and the aliases to copy, see Installation.

What compact looks like

A normal controller action and its Smoower equivalent — identical behaviour, identical compiled IL:

[HttpGet("{id}")]
public async Task<IActionResult> Get(int id)
{
    var x = await _db.Users
        .AsNoTracking()
        .Where(u => u.Id == id)
        .Select(u => new { u.Id, u.Name, u.Email })
        .FirstOrDefaultAsync();
    return x == null ? NotFound() : Ok(x);
}
[HG("{id}")]public Tr Get(int id)=>db.Users.nt().w(x=>x.Id==id).s(x=>new{x.Id,x.Name,x.Email}).ok1();

ok1() runs the query and returns 200 with the row, or 404 if missing — exactly the x == null ? NotFound() : Ok(x) above, folded into the call. How it works walks through why this saves tokens.

Where to next