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 🙏

© 2026 – Pkg Stats / Ryan Hefner

ioe-rf-calculations

v0.3.1

Published

IOE RF/Microwave calculation utilities and ready-made React components: single & double stub matching, transistor stability, power gain, maximum gain, and microwave filter design.

Readme

RF-IOE-Calculations

npm version npm license React

RF/Microwave calculation utilities and ready-made React components for undergraduate RF & microwave engineering (IOE curriculum).

npm install ioe-rf-calculations


Table of Contents


Features

| Tool | Component | Function | Description | | --- | --- | --- | --- | | Single Shunt-Stub Matching | <SingleStubMatch /> | singleStubMatch | Stub position & length (open/short) for impedance matching | | Double Shunt-Stub Matching | <DoubleStubMatch /> | doubleStubMatch | Two-stub matching with configurable spacing | | Transistor Stability Analysis | <StabilityAnalyzer /> | analyzeStability | K, μ, μ′ tests, Δ, stability circles | | Bilateral & Unilateral Power Gain | <PowerGain /> | calculateGain | GP, GA, GT with S-parameters | | GaAs FET Maximum Gain | <MaxGain /> | calculateMaxGain | Max gain + single-stub matching networks | | Microwave Filter Design | <FilterDesign /> | designFilter | Butterworth/Chebyshev LPF, HPF, BPF, BSF |

  • Two APIs in one package: pure calculation functions usable anywhere (Node, browser, plain JS/TS) and ready-made React calculator components.
  • Plain CSS, no frameworks: components are styled with a single hand-written stylesheet (rf-components.css) — no Tailwind, no Radix, no CVA, no CSS-in-JS, no icon libraries. Visual style matches the NerdStudyHub admin interface's own components.
  • Optional onInsert prop: get results as HTML to embed into any rich-text editor or anywhere else you need.
  • MIT licensed.

Installation

npm install ioe-rf-calculations

Peer dependencies:

| Package | Version | | --- | --- | | react | >= 18 | | react-dom | >= 18 |

The package has zero runtime dependencies — no need to install Tailwind or anything else.


Styling

The React components use plain CSS (no Tailwind classes, no CSS variables, no library). Import the stylesheet once in your app:

// main.tsx / App entry — anywhere before rendering the components
import "ioe-rf-calculations/rf-components.css";

…or via a <link> tag:

<link rel="stylesheet" href="https://unpkg.com/ioe-rf-calculations/rf-components.css" />

That's it — the components are fully styled and ready to render. There is nothing else to configure.


React components

Individual tools

Render any tool as a complete, self-contained calculator. Just drop the component in — it brings its own inputs, buttons, and results UI:

import { SingleStubMatch } from "ioe-rf-calculations";

export function MyPage() {
  return (
    <SingleStubMatch />
  );
}

Or use several together:

import {
  SingleStubMatch,
  DoubleStubMatch,
  StabilityAnalyzer,
  PowerGain,
  MaxGain,
  FilterDesign,
} from "ioe-rf-calculations";

export function MyPage() {
  return (
    <div className="mx-auto max-w-3xl space-y-8">
      <SingleStubMatch />
      <StabilityAnalyzer />
      <FilterDesign />
    </div>
  );
}

All-in-one selector

import { RFAnalysisSelector } from "ioe-rf-calculations";

export function ToolsPage() {
  return <RFAnalysisSelector />;
}

RFAnalysisSelector renders a card grid of all six tools and lets users switch between them — perfect for a single "Calculators" page.

Component API

Every tool component can be used with no props at all — it renders everything it needs (<SingleStubMatch />). There is one optional prop:

| Prop | Type | Description | | --- | --- | --- | | onInsert | (html: string) => void | Optional. Receives the results rendered as HTML when the user clicks "Insert into Content". Useful when you want to capture the results programmatically. |

MaxGain also accepts an optional freqGHz frequency field for cm-dimension stub matching.

Building blocks

Want to compose your own calculator UI? The shared building blocks are exported:

import {
  ToolCard,       // Card wrapper with title + description
  Field,          // labeled Input
  FieldGrid,      // responsive 2-col grid of Fields
  ActionBar,      // Calculate + Insert buttons
  ResultCard,     // results container
  ResultSection,  // titled result group
  ResultRow,      // label → value row (with optional StatusBadge)
  StatusBadge,    // ✓ / ✗ status badge
  SParameterInputs, // reusable S11/S12/S21/S22 mag+angle inputs
  Divider,
} from "ioe-rf-calculations";

Calculation functions (framework-free)

Import any function directly — no React, no Tailwind required.

import {
  singleStubMatch,
  doubleStubMatch,
  analyzeStability,
  calculateGain,
  calculateMaxGain,
  designFilter,
  fromPolar,
} from "ioe-rf-calculations";

Complex number helpers

The library represents complex numbers as { re: number; im: number } objects.

import { complex, add, sub, mul, div, conjugate, abs, phase, fromPolar, toPolar, formatComplex, formatPolar, db } from "ioe-rf-calculations";

const z = complex(3, 4);        // 3 + j4
fromPolar(1, 45);               // from magnitude + angle (degrees)
toPolar(z);                     // { mag: 5, angleDeg: 53.13 }
formatComplex(z);               // "3.0000 + j4.0000"
formatPolar(fromPolar(1, 45));  // "1.0000 ∠ 45.00°"
db(10);                         // 20 (10x power -> 20 dB)

Single stub matching

const result = singleStubMatch({
  inputType: "gamma",        // "gamma" | "zl"
  Z0: 50,
  freqGHz: 2.4,              // optional — adds cm dimensions
  gammaMag: 0.7,             // used when inputType === "gamma"
  gammaAngle: 120,           // degrees
  // or, for inputType === "zl":
  // zlRe: 25, zlIm: 10,
});

console.log(result.ZL, result.Gamma, result.VSWR);
console.log(result.zL, result.yL);

result.solutions.forEach((sol) => {
  console.log(sol.d, sol.b_stub, sol.open, sol.short);
});
// → stub position (λ), stub susceptance, open & short stub lengths (λ + cm when freqGHz is set)

Double stub matching

const result = doubleStubMatch({
  inputType: "zl",
  Z0: 50,
  zlRe: 25,
  zlIm: 10,
  d1Lambda: 0.25,      // distance from load to first stub
  spacingLambda: 0.375, // stub separation in wavelengths
});

if (result.solutions.length === 0) {
  console.log("No solution exists for this configuration.");
} else {
  result.solutions.forEach((sol) => {
    console.log(sol.B_total, sol.b_stub1, sol.b_stub2, sol.open1, sol.short1, sol.open2, sol.short2);
  });
}

Stability analysis

const result = analyzeStability({
  S11: fromPolar(0.6, 160),
  S12: fromPolar(0.05, 10),
  S21: fromPolar(2.5, -20),
  S22: fromPolar(0.5, -130),
});

console.log(result.Delta, result.Delta_mag);
console.log(result.K);           // Rollett stability factor
console.log(result.mu, result.mu_prime);
console.log(result.stability);   // e.g. "UNCONDITIONALLY STABLE"
console.log(result.CL, result.RL); // load stability circle (if any)
console.log(result.CS, result.RS); // source stability circle (if any)

Power gain

const result = calculateGain({
  S11: fromPolar(0.6, 160),
  S12: fromPolar(0.05, 10),
  S21: fromPolar(2.5, -20),
  S22: fromPolar(0.5, -130),
  Z0: 50,
  ZS: 50,
  ZL: 50,
});

// Bilateral (S12 ≠ 0)
console.log(result.Gamma_S, result.Gamma_L, result.Gamma_in, result.Gamma_out);
console.log(result.GP_B, result.GA_B, result.GT_B);

// Unilateral (S12 = 0 approximation)
console.log(result.GP_U, result.GA_U, result.GT_U);

Maximum gain (GaAs FET)

const result = calculateMaxGain(
  fromPolar(0.6, 160),  // S11
  fromPolar(0.05, 10),  // S12
  fromPolar(2.5, -20),  // S21
  fromPolar(0.5, -130), // S22
  50,                   // Z0
  9.5                   // freqGHz — optional, adds cm stub dimensions
);

console.log(result.isUnconditional, result.K, result.Delta_mag);

// Bilateral design: ΓS, ΓL, GT,max + single-stub input/output matching networks
console.log(result.bilateral.Gamma_S, result.bilateral.Gamma_L, result.bilateral.GT_max);
console.log(result.bilateral.inputMatch[0]);  // { d, open, short }
console.log(result.bilateral.outputMatch[0]);

// Unilateral design (S12 = 0)
console.log(result.unilateral.Gamma_S, result.unilateral.Gamma_L, result.unilateral.GTU_max);

Filter design

const result = designFilter({
  approximation: "chebyshev",    // "butterworth" | "chebyshev"
  filterType: "lpf",             // "lpf" | "hpf" | "bpf" | "bsf"
  N: 3,                          // optional — computed from specs if omitted
  fc: 2.4,                       // cutoff frequency (GHz) for LPF / HPF
  fx: 3.5,                       // attenuation frequency (GHz)
  attenuation_db: 30,            // required attenuation @ fx
  ripple_db: 0.2,                // Chebyshev only
  f1: 1.8,                       // lower cutoff (GHz) for BPF / BSF
  f2: 2.4,                       // upper cutoff (GHz) for BPF / BSF
  Z0: 50,
});

console.log(result.N);       // computed order
console.log(result.g);       // prototype g-values
result.elements.forEach((el) => {
  console.log(el.k, el.topology, el.L, el.C);
});

Recipes

Capture results as HTML (any editor)

Use the optional onInsert prop to grab the results as HTML — for a rich-text editor, a preview pane, or anything else:

import { useState } from "react";
import { SingleStubMatch } from "ioe-rf-calculations";

export function CalculatorWithOutput() {
  const [html, setHtml] = useState("");
  return (
    <>
      <SingleStubMatch onInsert={setHtml} />
      {html && <div dangerouslySetInnerHTML={{ __html: html }} />}
    </>
  );
}

Public calculator page

import { RFAnalysisSelector } from "ioe-rf-calculations";

export default function CalculatorsPage() {
  return (
    <section className="container py-10">
      <h1 className="mb-6 text-2xl font-bold">RF/Microwave Calculators</h1>
      <RFAnalysisSelector />
    </section>
  );
}

Use in plain Node.js

npm install ioe-rf-calculations
import { designFilter } from "ioe-rf-calculations"; // ESM
// const { designFilter } = require("ioe-rf-calculations"); // CJS

const f = designFilter({
  approximation: "butterworth",
  filterType: "lpf",
  fc: 2.4,
  fx: 3.5,
  attenuation_db: 30,
  Z0: 50,
});
console.log(f.N, f.elements);

Development

git clone https://github.com/SahajShakya/RF-IOE-Calculations.git
cd RF-IOE-Calculations
npm install
npm run build      # typecheck + vite library build → dist/
npm run typecheck  # tsc --noEmit only

The repo mirrors the two-layer design:

src/
├── calculations.ts   # pure RF/microwave math (framework-free)
├── components/       # React tool components built on the primitives below
└── lib/              # tiny class-name helper (no external deps)

The styling for every component lives in rf-components.css (plain CSS, no Tailwind, no UI library), styled to match the NerdStudyHub admin UI's own components (Card, InputField, SelectField, SubmitButton). There is no UI library to configure — just import the stylesheet.

Contributing

  1. Fork the repository.
  2. Create a feature branch (git checkout -b feat/my-feature).
  3. Commit your changes.
  4. Open a pull request.

Bug reports and new RF/microwave tool ideas are welcome via Issues.


License

MIT © 2026 Sahaj Shakya