Effect SDK

Use the Effect SDK when your application already composes services with Effect, or when an in-process transport needs the full calculator run response. Most server-side TypeScript applications should start with the Plain SDK.

Runtime graph

ts
Production: SDK Effect full run

Effect consumer
  -> calculateRunRequest(descriptor, request)
    -> PublicCalculatorService.calculate
      -> CalculatorRunResponse
    -> descriptor output decode for response.report
    -> typed CalculatorRunResponse with narrowed report

Report-only helpers
  -> calculateReportRequest(...)
    -> calculateRunRequest(...)
    -> response.report
  -> calculateReport(...)
    -> calculateReportRequest(...)

Return the full run response

Use calculateRunRequest when you need the canonical CalculatorRunResponse shape with a descriptor-decoded report type. Omitted request fields use their Schema defaults. Explicit context and help use nested Options: outer None means a missing key, Some(None) means a present undefined key and Some(Some(value)) means a present value. JSON clients keep the usual optional fields; the codec handles this conversion.

ts
import { audFromCents } from "@taxkit/core/primitives";
import { calculateRunRequest } from "@taxkit/sdk/effect";
import { AuAnnualIncomeTaxCalculation } from "@taxkit/sdk/au/effect";
import { Effect, Option } from "effect";

const effect = Effect.gen(function* () {
  const taxableIncome = yield* audFromCents(9_000_000);
  return yield* calculateRunRequest(AuAnnualIncomeTaxCalculation, {
    payload: {
      facts: { taxableIncome },
      jurisdiction: Option.some(
        Option.some(AuAnnualIncomeTaxCalculation.jurisdiction)
      ),
      taxYear: Option.some(Option.some(AuAnnualIncomeTaxCalculation.taxYear)),
    },
  });
});

Return only the report

Use calculateReportRequest when you have a full request payload but only need the report.

ts
import { audFromCents } from "@taxkit/core/primitives";
import { calculateReportRequest } from "@taxkit/sdk/effect";
import { AuAnnualIncomeTaxCalculation } from "@taxkit/sdk/au/effect";
import { Effect, Option } from "effect";

const effect = Effect.gen(function* () {
  const taxableIncome = yield* audFromCents(9_000_000);
  return yield* calculateReportRequest(AuAnnualIncomeTaxCalculation, {
    payload: {
      facts: { taxableIncome },
      jurisdiction: Option.some(
        Option.some(AuAnnualIncomeTaxCalculation.jurisdiction)
      ),
      taxYear: Option.some(Option.some(AuAnnualIncomeTaxCalculation.taxYear)),
    },
  });
});

Use calculateReport when you already have descriptor-typed facts:

ts
import { Cents, aud } from "@taxkit/core/primitives";
import { calculateReport } from "@taxkit/sdk/effect";
import { AuAnnualIncomeTaxCalculation } from "@taxkit/sdk/au/effect";

const effect = calculateReport(AuAnnualIncomeTaxCalculation, {
  taxableIncome: aud(Cents.make(9_000_000)),
});

Use an Effect client

ts
import { Cents, aud } from "@taxkit/core/primitives";
import { createClient } from "@taxkit/sdk/effect";
import {
  AuIncomeTax2025_26Module,
  AuAnnualIncomeTaxCalculation,
} from "@taxkit/sdk/au/effect";

const client = createClient(AuIncomeTax2025_26Module);

const effect = client.calculations.calculateReport(
  AuAnnualIncomeTaxCalculation,
  { taxableIncome: aud(Cents.make(9_000_000)) }
);

Requirements

Effect helpers require PublicCalculatorService in the environment. Each plain SDK client owns its runtime and must be disposed when finished; direct helpers clean up before returning. The Effect SDK leaves service provision to the consumer so application layers and tests can choose the calculator service implementation.