npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

gc-letters

v1.1.5

Published

An npm package for Government of Canada departments to generate Federal Identity Program (FIP) compliant letters as PDFs

Readme

gc-letters

npm version License: MIT

An npm package for Government of Canada departments to generate Federal Identity Program (FIP) compliant letters as PDFs directly in the browser.

Features

  • FIP Compliant - Follows Government of Canada Federal Identity Program standards
  • Browser-Based - No server required; generates PDFs client-side using jsPDF
  • Markdown Support - Write letter content in markdown for easy formatting (including tables)
  • React Components - Simple, declarative API using React
  • Flexible Typography - Control fonts, sizes, spacing at document and block levels
  • Page Management - Automatic page breaks, page numbering, and next-page indicators
  • Letter Metadata - Support for letter numbers, versions, and tracking
  • Multiple Page Sizes - Letter, Legal, and A4 formats
  • TypeScript - Full TypeScript support with type definitions

Installation

npm install gc-letters

Peer Dependencies

Requires React 17, 18, or 19:

npm install react react-dom

Quick Start

import React, { useState } from 'react';
import { GcLetter, LetterBlock } from 'gc-letters';

function MyLetter() {
  const [downloadFn, setDownloadFn] = useState(null);

  return (
    <div>
      <button onClick={() => downloadFn?.()}>
        Download PDF
      </button>

      <GcLetter
        fileName="my-letter"
        deptSignature="https://example.com/signature.png"
        onReady={(download) => setDownloadFn(() => download)}
      >
        {/* Note: Use {` ... `} for multi-line markdown content */}
        <LetterBlock>{`# Dear Recipient

This is my letter written in **markdown**.

## Key Points

- First point
- Second point
- Third point

Thank you for your attention.`}</LetterBlock>
      </GcLetter>
    </div>
  );
}

Components

GcLetter

Main wrapper component that handles document-level settings and PDF generation.

<GcLetter
  fileName="my-letter"                    // Required: PDF filename
  deptSignature="https://..."              // Required: Department signature URL
  pageType="letter"                        // Optional: 'letter' | 'legal' | 'a4'
  showPageNumbers={true}                   // Optional: Display page numbers
  onReady={(download) => download()}       // Optional: Callback with download function
>
  {children}
</GcLetter>

See API Reference for complete props documentation.

LetterBlock

Content section component for rendering markdown.

{/* Option 1: Using content prop */}
<LetterBlock
  content="# Heading\n\nParagraph text"
  allowPagebreak={true}
  textAlign="left"
/>

{/* Option 2: Using children (recommended for readability) */}
<LetterBlock allowPagebreak={true}>
{`# Heading

Paragraph text with **bold** and *italic*.

- List item 1
- List item 2`}
</LetterBlock>

💡 Important: For multi-line markdown content, you must use template literals with curly braces: {...}. This preserves newlines in your markdown. Without them, React will collapse multi-line content into a single line, breaking your formatting.

{/* ✅ Correct - Template literal preserves newlines */}
<LetterBlock>{`
Line 1

Line 2
`}</LetterBlock>

{/* ❌ Wrong - JSX collapses whitespace */}
<LetterBlock>
  Line 1

  Line 2
</LetterBlock>

{/* ✅ Alternative - Use content prop with \n */}
<LetterBlock content="Line 1\n\nLine 2" />

Supported Markdown:

  • Headings: #, ##, ###
  • Bold: **text**
  • Italic: *text*
  • Lists: - item or 1. item
  • Tables: Standard markdown table syntax with column alignment

SeparatorLine

Horizontal line for visual separation.

<SeparatorLine
  topMargin="5mm"      // Optional: spacing before line
  bottomMargin="10mm"  // Optional: spacing after line
/>

Default spacing: 1x paragraph spacing above, 2x below

Examples

Basic Letter

<GcLetter fileName="basic" deptSignature="https://...">
  <LetterBlock>
    Simple letter content.
  </LetterBlock>
</GcLetter>

Multi-Page with Page Numbers

<GcLetter
  fileName="multi-page"
  deptSignature="https://..."
  showPageNumbers="skip-first"
  pageNumberFormat="Page #"
  showNextPage={true}
>
  <LetterBlock content={longContent} />
</GcLetter>

Custom Formatting

<GcLetter
  fileName="formatted"
  deptSignature="https://..."
  fontFace="Times"
  textSizeNormal="12pt"
  paragraphSpacing="15mm"
>
  <LetterBlock content="# Title" textAlign="center" />
  <LetterBlock content="Body text" />
  <LetterBlock content="Signature" textAlign="right" />
</GcLetter>

Tables

Markdown tables are fully supported with column alignment:

<LetterBlock content={`
| Item | Q1 | Q2 | Q3 | Q4 | Total |
|------|---:|---:|---:|---:|------:|
| Revenue | $2.5M | $2.8M | $3.1M | $2.6M | $11.0M |
| Expenses | $1.8M | $2.1M | $2.3M | $1.9M | $8.1M |
| **Net** | **$0.7M** | **$0.7M** | **$0.8M** | **$0.7M** | **$2.9M** |
`} />

Table styling options (optional props on LetterBlock):

  • tableTheme - 'striped' | 'grid' | 'plain' (default: 'grid')
  • tableHeaderBold - Bold headers (default: true)
  • tableHeaderFillColor - Header background color RGB array
  • tableBorderColor - Border color RGB array

More examples: See examples/ directory

Documentation

FIP Compliance

This package helps create letters that comply with the Government of Canada's Federal Identity Program:

Requirements:

  • ✅ Helvetica typeface (default)
  • ✅ Department signature with flag symbol
  • ✅ Appropriate margins (38mm × 13mm default)
  • ✅ Bilingual support
  • ✅ Canada wordmark (included automatically in the package)

Read the FIP Compliance Guide for detailed requirements.

Browser Support

  • Chrome/Edge (latest)
  • Firefox (latest)
  • Safari (latest)
  • Not supported: Internet Explorer

TypeScript

Fully typed with TypeScript. Import types:

import type { GcLetterProps, LetterBlockProps, PageType, Alignment } from 'gc-letters';

Testing

The package includes comprehensive tests:

npm test              # Run all tests
npm test -- --coverage  # Run with coverage report

Test Coverage:

  • 124 tests passing
  • 87%+ coverage on utility functions
  • Visual test samples for manual verification

Development

# Install dependencies
npm install

# Run tests
npm test

# Build the package
npm run build

# Type check
npm run typecheck

# Lint
npm run lint

Important Notes

Component Nesting

⚠️ LetterBlock components cannot be nested. Each must be a direct child of GcLetter:

// ✅ Correct
<GcLetter {...props}>
  <LetterBlock content="First" />
  <LetterBlock content="Second" />
</GcLetter>

// ❌ Incorrect
<GcLetter {...props}>
  <LetterBlock>
    <LetterBlock /> {/* Will throw error */}
  </LetterBlock>
</GcLetter>

Image Loading

Supported image formats: PNG, JPG/JPEG only

⚠️ SVG is not supported by the underlying jsPDF library. Convert SVG files to PNG before use.

Department signatures must be accessible:

  • Same domain: Works automatically
  • External domain: Requires CORS configuration
  • For testing: Use data URLs
// ✅ Supported
deptSignature="signature.png"
deptSignature="signature.jpg"

// ❌ Not supported
deptSignature="signature.svg"  // Convert to PNG first

Roadmap

Future enhancements being considered:

  • [ ] Image embedding in markdown
  • [ ] Server-side rendering option
  • [ ] Additional fonts
  • [ ] Custom templates
  • [ ] Advanced table features (merged cells, custom cell styling)

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new features
  4. Ensure all tests pass
  5. Submit a pull request

See CONTRIBUTING.md for details.

License

MIT © [Your Organization]

See LICENSE file for details.

Support

Acknowledgments

Built with:

Related Resources


Made with 🍁 for the Government of Canada

Disclaimer

This project is currently a proof of concept and is not officially endorsed as a Government of Canada tool. While it aims to help generate FIP-compliant letters, it should be used for development and testing purposes only. Organizations should conduct their own compliance reviews before using this package in production environments.