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

pmss

v0.0.1

Published

Cascading JavaScript settings

Readme

Preference Management Style Sheets

This is intended as a language for settings. The name might be a placeholder. Or final. Who knows?

XKCD Standards Comic

Why? WHY???

The raison d'etre is that settings cascade and override. In most cases, we would like to have (e.g. for a learning management system):

  • Rosters from Google Classroom
  • Except for Central Valley School District, which uses Instructure
  • Except for Maplewood Elementary School, which uses Canvas
  • Except for Mrs. Johnson's afterschool program, which keeps rosters in a Google Spreadsheet, by virtue of excepting the general community and not just district students.

We'd also like to have:

  • System defaults
  • Overridden by system settings in /etc/foo
  • Overridden by user settings in ~/.foo
  • Overridden by environment variables
  • Overridden by settings in a database
  • Overridden by command line parameters and settings set within the program

In most cases, this generates a spaghetti-like set of special cases and one-offs as systems reach maturity. Very few systems have good ways for settings to cascade. The ones which do create custom ad-hoc languages.

What does cascade? CSS. It's a well-specificed, well-documented syntax. As a result, we use a subset of CSS syntax as our native format.

Mindful of backwards-compatibility, it is possible to integrate PMSS into most systems piecemeal. We also have an opinioned, streamlined API which will hopefully make it easy to get started.

What else is needed?

  • [ ] Validation and reasonable errors
    • [x] Robust typing, with conversions and validation
    • [x] Validation all required fields are provided
    • [ ] Above, considering contexts
    • [x] Validation all fields are declared
    • [ ] Above, for classes and attributes
  • [x] Human-friendly (and ideally, standardized) formats. We don't want to reinvent yaml / json / XML / etc.
  • [x] Comments
  • [ ] Interpolation / DRY / single source of truth
    • [ ] If system_dir is /opt/system, we'd like to be able to set tokens to e.g. ${system_dir}/tokens.rsa
    • [ ] Some systems take this further to full Turing-complete automation
    • [ ] THIS IS DANGEROUS IF SETTINGS CAN COME FROM A USER, so it should be behind a flag. Otherwise, you'll have background_color set to ${secret_id} ${access_key} ${password}.
  • [ ] Multiple file support. Large config files should be able to break down into smaller ones
    • [ ] This should be configurable and safe. We don't want someone to include /etc/passwd or similar.
  • [ ] Security. We'd like to be immune to things like injection attacks, which do come up if setting come from e.g. web forms.
  • [x] Some support for configuring plug-ins / modules
    • [x] This probably means some level of successive loading, with setting available before the full system is loaded.
  • [ ] Lists / aggregations. E.g. if we want to set up a list of modules to import, each with its own settings.
  • [ ] Classes provided on the command line
  • [x] Dynamic reloading. If a file changes, settings update without a restart. Note this is currently more useful for development than deployment until we have more safety checks.
    • [ ] Robust validation and error handling on a reload.
  • [ ] Robust test infrastructure
  • [ ] Nice documentation
  • [ ] pypi package (this might need a rename, since pmss is taken!)
  • [ ] INI file support, to give an example of how to handle backwards-compatibility
  • [ ] Better error messages
  • [ ] Nicer usage()
  • [ ] Selectors on the commandline
  • [ ] Classes on the commandline

Note that we don't have all of this yet.

Simplified API

From Python:


import pmss

settings = pmss.init(
    prog="lo",
    description="A system for monitoring",
    epilog="For more information, see PMSS documentation."
)

pmss.register_field(
    name="server_port",
    command_line_flags=["-p", "--port"],
    type=pmss.TYPES.port,
    description="The port our system should run on.",
    default=8888
)

pmss.register_field(
    name="hostname",
    type=pmss.TYPES.hostname,
    description="The hostname",
    required=True
)

pmss.validate(settings)
normal_port = settings.server_port()
exception_port = settings.server_port(attributes={'school': 'middlesex'})

Our settings file (can be placed in the standard locations):

* {
    _biff: baz;
    hostname: testhost;
    server_port: 80;
}

[school=middlesex] {
    server_port: 8080;
}

And from the commandline:

python example.py --port=90 --hostname=testhosttwo

What's the model

We're basing this on CSS. Why?

  • They cascade
  • They're well-specified and libraries exist
  • Many people know CSS

The downside, of course, is that many people find CSS a bit complex.

Conceptually, we plan to have series of rule sets. E.g.:

    add_ruleset(args=sys.argsv)
    add_ruleset(file="~/.settings.pmss", name="User settings file", classes=["settings_file"], interpolation=True)
    add_ruleset(environ=sys.environ, id="environ")
    delete_ruleset(id="environ")

We also plan to have series of schemas, registered in code. Modules can define schemas too. For example, a cloud service module could define that it wants API keys.

Once everything is loaded, we can run:

    validate()

Note that settings are usable (just not guaranteed correct) before validation, as e.g. command line arguments might point to a settings file and a series of modules to load, and validation might be impossible until those are loaded.

We're trying to make this batteries included, so by default, the rulesets look in the standard locations (~, /etc, etc.) and on the commandline.

We do not look at parent / child relationships, so the following are both okay:

    auth {
        google {...}
        microsoft {...}
        github {...}
    }
    rosters {...}

or:

   google {
       auth {...}
       rosters {...}
       docs {...}
   }

   microsoft {...}

For debugging, we can have fine-grained settings

if settings.verbose(types=['pmss', 'selectors']):
   print("....")

And we can decide what to make verbose from the command line whether to run --verbose=True or --pmss:verbose=True or otherwise.

Likewise, we can define classes for e.g. prod and dev:

.prod {
    database: postgresql;
}

.dev {
    database: sqlite;
}

Files

  • pmsslex.py and pmssyacc.py are the lexer and parser for our variant of CSS. These are designed to be interchangeable if you'd like e.g. full CSS or an INI file or whatnot.
  • pmsstypes.py handles type validation and conversion. We use other libraries where possible, to maintain compatible formats. Conversely, this is usable without the rest of the system.

Implementations

Python

The original Python implementation in python/pmss/ is in the pilot stage, has gaps, but it is sufficiently mature we have used it in production to provide comprehensive type validation and configuration management.

JavaScript/TypeScript (Prototype)

A prototype JavaScript/TypeScript implementation is available in javascript/. This uses Peggy for parsing and provides full ES module support.

Setup

cd javascript
npm install
npm run build
npm test

Development

# Build TypeScript
npm run build

# Run tests
npm test

# Watch mode
npm run test:watch

# Generate parsers from grammar
npm run generate

Debugging

A utility script for parsing and inspecting PMSS files:

node --loader ts-node/esm src/scripts/parse-pmss.ts <file>

Cross-Validation

Both Python and TypeScript implementations run the same test fixtures to ensure compatibility:

  • fixtures/simple.pmss + .queries
  • fixtures/deadlines.pmss + .queries
  • fixtures/i18n.pmss + .queries

Dependencies

  • peggy - PEG parser generator for JavaScript
  • zod - Runtime type validation (prepared for future type system)
  • typescript - Language and build toolchain
  • @types/node - Node.js type definitions

Who else has thought about this?

  • Build tools
  • Web servers
    • nginx has a similar set of constraints around routes
  • Command line parsers
  • Configuration languages
    • Dhall has very nice tooling which can visualize if a change to a file led to a change in output configuration, as well as diffs to see what the change was.
    • configparser is the Python default, very much based on INI files. Good ideas include interpolation.
  • Schemas. There's a whole theory of types, which is out-of-scope for this list (but in-scope for a grad-level course).
    • The best schema definition language seems to be Cue which is in Go, but has basic Python integration. We should probably use this verbatim.
    • XML DTDs
    • JSON Schema
    • Traitlets thought a little bit about validation, although it seems to mix models in a way I don't like.
  • CSS does most of what we want
    • tinycss2 seems like the right parser to work from.
    • SASS builds on it with useful shortcuts. Should we adopt SASS extensions?
  • Configuration languages
    • pkl was recently released by Apple. It seems to have some very nice ideas, but misses a lot as well. See also HN discussion. Well worth reviewing, if not adopting.
    • gcl has nice copy about configuration. The language itself is very Turing-complete, which makes it a bit awkward. It's a little like having a code file, config.py.
    • hcl Seems nice.
    • JSonnet has nice ideas, but seems to confuse templates and inheritence. Cue, above, is a reaction to this confusion.