Skill: unit-conversion

## Overview

7 stars

Best use case

Skill: unit-conversion is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

## Overview

Teams using Skill: unit-conversion should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/unit-conversion/SKILL.md --create-dirs "https://raw.githubusercontent.com/heldernoid/agentic-build-templates/main/projects/web-applications/recipe-scaler/skills/unit-conversion/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/unit-conversion/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How Skill: unit-conversion Compares

Feature / AgentSkill: unit-conversionStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

## Overview

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Skill: unit-conversion

## Overview

Kitchen unit conversion library for recipe scaling. Converts between US customary volume (tsp, tbsp, cup, fl oz, pint, quart) and metric volume (ml, L), and between weight units (g, kg, oz, lb). Includes smart unit selection to pick the most human-readable unit for a given quantity.

## Unit Families

### Volume (base: milliliters)

| Unit | ml equivalent | Abbreviations |
|------|--------------|---------------|
| tsp | 4.92892 | t, tsp, teaspoon |
| tbsp | 14.7868 | T, tbsp, tablespoon |
| fl oz | 29.5735 | fl oz, fluid ounce |
| cup | 236.588 | c, cup, cups |
| pint | 473.176 | pt, pint |
| quart | 946.353 | qt, quart |
| gallon | 3785.41 | gal, gallon |
| ml | 1 | ml, mL, milliliter |
| L | 1000 | L, l, liter |

### Weight (base: grams)

| Unit | grams equivalent | Abbreviations |
|------|-----------------|---------------|
| g | 1 | g, gram |
| kg | 1000 | kg, kilogram |
| oz | 28.3495 | oz, ounce |
| lb | 453.592 | lb, pound |

## Core Functions

```typescript
type UnitSystem = 'us' | 'metric';

// Convert qty from fromUnit to toUnit
export function convertUnit(qty: number, fromUnit: string, toUnit: string): number

// Return qty + most readable unit for system
export function smartUnit(qty: number, unit: string, system?: UnitSystem): { qty: number; unit: string }

// Parse unit alias to canonical name
export function canonicalUnit(alias: string): string | null

// Check if two units are compatible (same family)
export function unitsCompatible(a: string, b: string): boolean
```

## Unit Alias Resolution

```typescript
const ALIASES: Record<string, string> = {
  // Volume
  't': 'tsp', 'tsp': 'tsp', 'teaspoon': 'tsp', 'teaspoons': 'tsp',
  'T': 'tbsp', 'tbsp': 'tbsp', 'tablespoon': 'tbsp', 'tablespoons': 'tbsp',
  'c': 'cup', 'cup': 'cup', 'cups': 'cup',
  'pt': 'pint', 'pint': 'pint', 'pints': 'pint',
  'qt': 'quart', 'quart': 'quart', 'quarts': 'quart',
  'gal': 'gallon', 'gallon': 'gallon',
  'fl oz': 'fl oz', 'fluid ounce': 'fl oz', 'fluid ounces': 'fl oz',
  'ml': 'ml', 'mL': 'ml', 'milliliter': 'ml', 'milliliters': 'ml',
  'l': 'L', 'L': 'L', 'liter': 'L', 'liters': 'L',
  // Weight
  'g': 'g', 'gram': 'g', 'grams': 'g',
  'kg': 'kg', 'kilogram': 'kg', 'kilograms': 'kg',
  'oz': 'oz', 'ounce': 'oz', 'ounces': 'oz',
  'lb': 'lb', 'lbs': 'lb', 'pound': 'lb', 'pounds': 'lb',
};

export function canonicalUnit(alias: string): string | null {
  return ALIASES[alias.trim()] ?? null;
}
```

## Smart Unit Selection Rules

### US Customary Volume

| Total volume | Display as |
|-------------|-----------|
| < 1 tsp | fractional tsp |
| 1 tsp - 2 tbsp | tsp |
| 3 tbsp - 3 tbsp | tbsp |
| 4 tbsp (= 1/4 cup) - 3/4 cup | cup (prefer cup fractions) |
| 1 cup - 2 cups | cup |
| 2 cups - 4 cups | pint or cups |
| 4 cups + | quart |

### Metric Volume

| Total volume | Display as |
|-------------|-----------|
| < 5 ml | ml |
| 5-250 ml | ml |
| 250 ml - 999 ml | ml or cup |
| 1000 ml + | L |

### Weight

| Total weight | US | Metric |
|-------------|-----|--------|
| < 28 g | g | g |
| 28-454 g | oz | g |
| 454+ g | lb | kg |

## Full Implementation

```typescript
const ML: Record<string, number> = {
  tsp: 4.92892,
  tbsp: 14.7868,
  'fl oz': 29.5735,
  cup: 236.588,
  pint: 473.176,
  quart: 946.353,
  gallon: 3785.41,
  ml: 1,
  L: 1000,
};

const G: Record<string, number> = {
  g: 1,
  kg: 1000,
  oz: 28.3495,
  lb: 453.592,
};

export function convertUnit(qty: number, from: string, to: string): number {
  const fromC = canonicalUnit(from) ?? from;
  const toC = canonicalUnit(to) ?? to;

  if (fromC === toC) return qty;

  if (ML[fromC] !== undefined && ML[toC] !== undefined) {
    return qty * ML[fromC] / ML[toC];
  }

  if (G[fromC] !== undefined && G[toC] !== undefined) {
    return qty * G[fromC] / G[toC];
  }

  throw new Error(`Incompatible units: ${from} and ${to}`);
}

export function unitsCompatible(a: string, b: string): boolean {
  const ac = canonicalUnit(a) ?? a;
  const bc = canonicalUnit(b) ?? b;
  return (ML[ac] !== undefined && ML[bc] !== undefined) ||
         (G[ac] !== undefined && G[bc] !== undefined);
}

export function smartUnit(qty: number, unit: string, system: UnitSystem = 'us'): { qty: number; unit: string } {
  const canonical = canonicalUnit(unit) ?? unit;

  if (!canonical || (!ML[canonical] && !G[canonical])) {
    // Count item - return as-is, rounded
    return { qty: Math.round(qty * 4) / 4, unit: unit };
  }

  if (ML[canonical] !== undefined) {
    return smartVolume(qty * ML[canonical], system);
  }

  return smartWeight(qty * G[canonical], system);
}

function smartVolume(totalMl: number, system: UnitSystem): { qty: number; unit: string } {
  let result: { qty: number; unit: string };

  if (system === 'metric') {
    if (totalMl < 200) result = { qty: totalMl / ML['ml'], unit: 'ml' };
    else if (totalMl < 950) result = { qty: totalMl / ML['ml'], unit: 'ml' };
    else result = { qty: totalMl / ML['L'], unit: 'L' };
  } else {
    if (totalMl < 4.93) result = { qty: totalMl / ML['tsp'], unit: 'tsp' };
    else if (totalMl < 14.79) result = { qty: totalMl / ML['tsp'], unit: 'tsp' };
    else if (totalMl < 29.57) result = { qty: totalMl / ML['tbsp'], unit: 'tbsp' };
    else if (totalMl < 473) result = { qty: totalMl / ML['cup'], unit: 'cup' };
    else if (totalMl < 946) result = { qty: totalMl / ML['pint'], unit: 'pint' };
    else result = { qty: totalMl / ML['quart'], unit: 'quart' };
  }

  return { qty: roundToClean(result.qty), unit: result.unit };
}

function smartWeight(totalG: number, system: UnitSystem): { qty: number; unit: string } {
  let result: { qty: number; unit: string };

  if (system === 'metric') {
    result = totalG < 1000
      ? { qty: totalG, unit: 'g' }
      : { qty: totalG / G['kg'], unit: 'kg' };
  } else {
    if (totalG < 28.35) result = { qty: totalG, unit: 'g' };
    else if (totalG < 453.6) result = { qty: totalG / G['oz'], unit: 'oz' };
    else result = { qty: totalG / G['lb'], unit: 'lb' };
  }

  return { qty: roundToClean(result.qty), unit: result.unit };
}

// Round to clean fractions (nearest 1/8)
function roundToClean(v: number): number {
  return Math.round(v * 8) / 8;
}
```

## Test Cases

```typescript
describe('convertUnit', () => {
  it('converts 1 cup to tbsp', () => {
    expect(convertUnit(1, 'cup', 'tbsp')).toBeCloseTo(16, 1);
  });
  it('converts 1 cup to ml', () => {
    expect(convertUnit(1, 'cup', 'ml')).toBeCloseTo(236.6, 0);
  });
  it('converts 1 lb to g', () => {
    expect(convertUnit(1, 'lb', 'g')).toBeCloseTo(453.6, 0);
  });
  it('handles alias: T -> tbsp', () => {
    expect(convertUnit(1, 'T', 'tsp')).toBeCloseTo(3, 1);
  });
});

describe('smartUnit', () => {
  it('picks tbsp for small volumes', () => {
    const r = smartUnit(0.25, 'cup');  // 4 tbsp
    expect(r.unit).toBe('tbsp');
    expect(r.qty).toBeCloseTo(4, 0);
  });
  it('keeps cup for > 4 tbsp', () => {
    const r = smartUnit(1.5, 'cup');
    expect(r.unit).toBe('cup');
  });
  it('uses metric ml for small metric volumes', () => {
    const r = smartUnit(100, 'ml', 'metric');
    expect(r.unit).toBe('ml');
  });
  it('uses L for large metric volumes', () => {
    const r = smartUnit(1200, 'ml', 'metric');
    expect(r.unit).toBe('L');
    expect(r.qty).toBeCloseTo(1.2, 1);
  });
});
```

Related Skills

Skill: Uptime Monitoring

7
from heldernoid/agentic-build-templates

## Overview

Skill: Status Page

7
from heldernoid/agentic-build-templates

## Overview

Skill: recipe-scaler

7
from heldernoid/agentic-build-templates

## Overview

reading-list

7
from heldernoid/agentic-build-templates

Operate the reading-list API to save, manage, tag, search, and export articles.

email-digest

7
from heldernoid/agentic-build-templates

Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.

websocket-realtime

7
from heldernoid/agentic-build-templates

Use the WebSocket connection in poll-builder to receive live vote updates. Use when you need to stream real-time poll results, monitor a poll for new votes, or build a live dashboard. Triggers include "live results", "real-time updates", "stream votes", "watch poll", or "WebSocket".

poll-builder

7
from heldernoid/agentic-build-templates

Self-hosted poll creation tool with real-time results. Use when you need to create a poll, check vote counts, close a poll, export results, or get the shareable link for a poll. Triggers include "create poll", "vote", "poll results", "survey", "collect votes", "share poll", or any task involving polling or voting.

Skill: personal-finance

7
from heldernoid/agentic-build-templates

## Overview

Skill: csv-import

7
from heldernoid/agentic-build-templates

## Overview

Skill: Syntax Highlighting

7
from heldernoid/agentic-build-templates

## Purpose

Skill: Pastebin Core

7
from heldernoid/agentic-build-templates

## Purpose

Skill: Cost Reporting

7
from heldernoid/agentic-build-templates

## Overview