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

@computis/effect-xml

v0.2.0

Published

XML decoding and encoding with Effect Schema, XSD validation, and an XSD to Effect Schema code generator.

Readme

@computis/effect-xml

Decode and encode XML with Effect Schema, validate it against an XSD, and generate the Schema from the XSD.

  • One Schema describes the XML: struct fields are elements in order, and the fields you list as attributes are attributes.
  • codec(schema) compiles the Schema once and returns decode (XML string to value) and encode (value to XML string). Both return an Effect.
  • make(schema, { xsd }) adds validate, which checks a document against the XSD with libxml2 compiled to WebAssembly. It reads no network resource and expands no external entity.
  • The effect-xml generate CLI turns an XSD into a TypeScript module of Effect Schemas, with the XSD facets (patterns, lengths, ranges, enumerations) as Schema checks.

Install

npm install @computis/effect-xml effect

It needs Effect 4. The package is ESM only. Its modules depend on no Effect platform package: the services they need, such as FileSystem, come from the platform layer you provide, so they work with @effect/platform-node, @effect/platform-bun or any other.

The effect-xml CLI needs one platform package next to it: @effect/platform-node on Node, @effect/platform-bun on Bun. To run it elsewhere, provide your platform's services to main from @computis/effect-xml/cli.

Decode and encode

import { Effect, Schema } from "effect";
import { codec, root } from "@computis/effect-xml";

const Note = Schema.Struct({
  lang: Schema.optionalKey(Schema.String),
  to: Schema.String,
  body: Schema.String,
}).pipe(root("note", { attributes: ["lang"] }));

const program = Effect.gen(function* () {
  const { decode, encode } = yield* Effect.fromResult(codec(Note));
  const note = yield* decode(`<note lang="en"><to>Ada</to><body>Hello</body></note>`);
  // { lang: "en", to: "Ada", body: "Hello" }
  return yield* encode({ ...note, body: "Hello again" });
});

codec returns a Result: it fails with XmlPlanError when the Schema has no XML representation, for example an optional field, which can hold undefined. Use optionalKey instead.

| Annotation | Meaning | | -------------------------------------------------- | ------------------------------------------------------------------------------ | | root(name, { attributes?, namespace?, prefix? }) | The root element: its name, the fields that are attributes, and its namespace. | | element({ attributes }) | A nested struct whose listed fields are attributes. |

| Option | Meaning | | ------------------------- | -------------------------------------------------------------------------------------- | | decoder.maxDepth | The deepest element nesting the decoder accepts. The default is 256. | | decoder.trimText | Removes the whitespace around the text of every leaf. The default keeps it as written. | | decoder.unknownElements | "error" (the default) or "skip" for elements the Schema does not declare. | | encoder.declaration | Writes the <?xml …?> declaration. | | encoder.indent | Indents the output with a number of spaces or a string. | | jit | Compiles the Schema with the Effect Schema JIT. The default is true. |

Validate against an XSD

import { NodeServices } from "@effect/platform-node";
import { Effect } from "effect";
import * as EffectXml from "@computis/effect-xml";

const program = Effect.gen(function* () {
  const notes = yield* EffectXml.make(Note, { xsd: { path: "note.xsd" } });
  yield* notes.validate(`<note><to>Ada</to><body>Hello</body></note>`);
}).pipe(Effect.scoped, Effect.provide(NodeServices.layer));

make compiles the XSD once and frees it when its scope closes. It reads the XSD and every schema it imports or includes through the FileSystem and Path services, so it works on any Effect platform, or on a FileSystem of your own. validate fails with XsdValidationError, whose message lists each issue with its line and column. The XSD can also come from memory: { contents: Uint8Array, url }, where url resolves the schemas it imports.

Generate the Schema from an XSD

effect-xml generate --xsd schema/order.xsd --root Order --out src/order.gen.ts

| Flag | Meaning | | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | --xsd | The XSD file. | | --root | The global element that becomes the root of the Schema. | | --out | The generated TypeScript file. | | --prefix | The prefix of the root element. It is required when the local elements of the XSD are unqualified. | | --runtime | The import specifier of the runtime helpers. The default is @computis/effect-xml/xsd-codegen/runtime. | | --domain | <module>#<export>: an object of functions keyed by XSD type name. Each receives the generated Schema and returns the Schema to use. <module> resolves from --out. | | --format | A command that reads the code on stdin and writes the formatted code on stdout. | | --format-arg | An argument of the --format command. Repeat it for each argument. {file} is replaced with the output path. |

The generated module exports one Schema per XSD type, and the root Schema is ready for codec and make. The same generator is available as a function from @computis/effect-xml/xsd-codegen.

License

MIT