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

state-safe-x

v1.0.0

Published

Lightweight runtime state and object validation with human-friendly errors

Readme

🛡️ state-safe-x

NPM version NPM downloads

Lightweight runtime state and object validation with human-friendly errors.


Why does state-safe-x exist?

Because JavaScript happily lets this happen:

const user = { age: "17" }

…and your app finds out much later, usually in production.

state-safe-x exists to answer one simple question:

“Is this object actually safe to use right now?”

Not at compile time. Not in theory. At runtime.


What is state-safe-x?

state-safe-x is a tiny library that guards your objects and state by validating them against a schema.

  • ✅ validates runtime data
  • ✅ supports nested objects & arrays
  • ✅ gives clear, human-friendly errors
  • ✅ has a non-throwing .safe() mode
  • ✅ works with ESM and CommonJS
  • ✅ zero dependencies

No magic. No heavy abstractions. Just protection.


Installation

npm install state-safe-x

Basic Usage

import { guard } from "state-safe-x"

const user = {
  name: "Alex",
  age: 17
}

guard(user, {
  name: "string",
  age: "number"
})

// If validation fails → throws StateGuardError
// If validation passes → returns the original object

Nested Objects

state-safe-x handles deep structures naturally.

const user = {
  profile: {
    age: 17,
    email: "[email protected]"
  }
}

guard(user, {
  profile: {
    age: "number",
    email: "string"
  }
})

Error paths are precise:

"profile.age" should be a number

Arrays & Typed Arrays

guard(
  { tags: ["js", "node", "esm"] },
  { tags: "string[]" }
)

If something goes wrong:

"tags[1]" should be a string

Optional Fields

Mark optional fields with ?.

guard(
  { name: "Alex" },
  { name: "string", email: "string?" }
)

.safe() — Non-Throwing Mode

Sometimes you don’t want exceptions. You just want the truth.

const result = guard.safe(
  { age: "17" },
  { age: "number" }
)

if (!result.success) {
  console.log(result.errors)
}

.safe() returns:

{
  success: false,
  data: { age: "17" },
  errors: [
    {
      path: "age",
      expected: "number",
      received: "string",
      message: "\"age\" should be a number"
    }
  ]
}

Perfect for:

  • forms
  • APIs
  • logging
  • batch validation

Error Handling

When using guard() (throwing mode), errors are instances of:

StateGuardError
try {
  guard(data, schema)
} catch (err) {
  if (err.name === "StateGuardError") {
    console.log(err.errors)
  }
}

Errors are structured and predictable — no guessing.


When should you use state-safe-x?

Use it when you want to:

  • validate API responses
  • guard application state
  • protect config objects
  • validate user input
  • avoid silent runtime bugs
  • fail fast, or fail safely

If you’ve ever written typeof x === "string" more than once — this is for you.


When not to use it?

  • If you only need compile-time types
  • If you want a massive, all-in-one validation framework
  • If runtime validation doesn’t matter for your use case

state-safe-x is intentionally focused and small.


Design Philosophy

  • Runtime first
  • Explicit > magical
  • Errors should be readable
  • APIs should be SIMPLE
  • Small surface area

This library is designed to grow without breaking users.


No rush. Stability first.


state-safe-x helps you sleep better by making sure your data is actually what you think it is.


👨‍💻 About the Author

Hi cinfinit here 👋

Built state-safe-x after writing one too many typeof, Array.isArray, and “this should be a number” checks scattered across codebases.

Wanted something that:

  • validates real runtime data
  • stays small and readable
  • doesn’t fight JavaScript’s nature
  • doesn’t pretend TypeScript solves everything
  • gives errors humans can actually understand

So instead of copy-pasting guards everywhere, got it centralized.

That’s all state-safe-x is:

a practical tool born out of real-world JavaScript pain.

No grand framework. No magic. Just safety where JavaScript needs it most.


If this library saves you from one production bug — it’s already done its job.


🧠 Final Note

If you find yourself thinking:

“I know this should be safe… but I wish I could be sure.”

That’s exactly why this exists.