PHPackages                             slack/hack-json-schema - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. slack/hack-json-schema

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

slack/hack-json-schema
======================

Hack JSON Schema generator

v4.102.15(2y ago)302.4k↓85.7%15[16 issues](https://github.com/slackhq/hack-json-schema/issues)[2 PRs](https://github.com/slackhq/hack-json-schema/pulls)Hack

Since Jul 25Pushed 1mo ago10 watchersCompare

[ Source](https://github.com/slackhq/hack-json-schema)[ Packagist](https://packagist.org/packages/slack/hack-json-schema)[ RSS](/packages/slack-hack-json-schema/feed)WikiDiscussions master Synced yesterday

READMEChangelog (10)Dependencies (6)Versions (59)Used By (0)

Hack JSON Schema
================

[](#hack-json-schema)

[![Build Status](https://camo.githubusercontent.com/65c69d589a6acc2b0014e66f5e60668e1775b0876e173e328bcf2cdf49fca801/68747470733a2f2f7472617669732d63692e6f72672f736c61636b68712f6861636b2d6a736f6e2d736368656d612e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/slackhq/hack-json-schema)

Hack JSON Schema is a library for validating JSON inputs, using JSON schemas, in Hack.

Given a JSON schema file, you can generate a validator in Hack to validate incoming JSON against the schema. If the JSON conforms to the schema, the validator will returned typed output.

There are several benefits to generation:

- We don't have to parse the JSON schema to validate the incoming object at runtime.
- We can output typed shapes that are generated from the JSON schema, increasing the type safety of downstream code.

Usage
-----

[](#usage)

### Codegen::forPath

[](#codegenforpath)

The most basic way to use this library is to generate a validator from a JSON schema file:

```
use type Slack\Hack\JsonSchema\Codegen\Codegen;

Codegen::forPath('/path/to/json-schema.json', shape(
  'validator' => shape(
    'file' => '/path/to/MyJsonSchemaValidator.php',
    'class' => 'MyJsonSchemaValidator',
  ),
))->build();
```

`/path/to/MyJsonSchemaValidator.php` now exists with a class:

```
final class MyJsonSchemaValidator extends BaseValidator {
  ... class contents
}
```

Each validator has a `validate` method, which takes a decoded JSON object:

```
$json = json_decode($args['json_input'], true);
$validator = new MyJsonSchemaValidator($json);
$validator->validate();
if (!$validator->isValid()) {
  print_r("invalid_json", $validator->getErrors());
  return;
}

// JSON is valid, get typed object:
$validated = $validator->getValidatedInput();
```

### Codegen::forPaths

[](#codegenforpaths)

If you have multiple JSON schemas that leverage the `$ref` attribute, you should prefer to use `Codegen::forPaths` over `Codegen::forPath`.

The workflow for `Codegen::forPath` is:

- Given a JSON schema, "de-reference" the schema. De-referencing is the process of resolving all of the `$ref` paths with their actual schema. This creates a single de-referenced schema.
- With the de-referenced schema, generate a validator.

This works well if you only have one primary schema, but if you have multiple schemas, each with common refs, you'll start to generate a lot of duplicate code.

In these cases, you can use `Codegen::forPaths`.

```
use type Slack\Hack\JsonSchema\Codegen\Codegen;

$schemas = vec['/path/to/json-schema-1.json', '/path/to/json-schema-2.json', '/path/to/json-schema-3.json'];
Codegen::forPaths($schemas, shape(
  'validator' => shape(
    'refs' => shape(
       'unique' => shape(
          'source_root' => '/path/to',
          'output_root' => '/path/gen'
        )
     )
  ),
))->build();
```

By defining the `source_root` and `output_root` we can generate unique validators per `$ref` we come across. We can then re-use those validators when generating other validators.

Developing
----------

[](#developing)

### Installing Dependencies

[](#installing-dependencies)

We handle all dependencies through Docker. It's as simple as:

```
make install
```

### Running Tests

[](#running-tests)

```
make test
```

Related Libraries
-----------------

[](#related-libraries)

This library was inspired by the ideas in these related libraries:

-
-

License
-------

[](#license)

Hack JSON Schema is MIT-licensed.

###  Health Score

48

—

FairBetter than 93% of packages

Maintenance51

Moderate activity, may be stable

Popularity31

Limited adoption so far

Community25

Small or concentrated contributor base

Maturity73

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~69 days

Recently: every ~125 days

Total

25

Last Release

860d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/fe0c790254e30bd794cc8d25e6debf75a6f91da36bebf539eb7f6706e4e0a1aa?d=identicon)[michaelhahn](/maintainers/michaelhahn)

---

Top Contributors

[![ianhoffman](https://avatars.githubusercontent.com/u/13488540?v=4)](https://github.com/ianhoffman "ianhoffman (85 commits)")[![lexidor](https://avatars.githubusercontent.com/u/31805625?v=4)](https://github.com/lexidor "lexidor (69 commits)")[![betsyalegria](https://avatars.githubusercontent.com/u/10287237?v=4)](https://github.com/betsyalegria "betsyalegria (11 commits)")[![ssandler](https://avatars.githubusercontent.com/u/1163725?v=4)](https://github.com/ssandler "ssandler (4 commits)")[![ajmacd](https://avatars.githubusercontent.com/u/920663?v=4)](https://github.com/ajmacd "ajmacd (3 commits)")[![sfdc-ospo-bot](https://avatars.githubusercontent.com/u/187804696?v=4)](https://github.com/sfdc-ospo-bot "sfdc-ospo-bot (3 commits)")[![ZachJBurns](https://avatars.githubusercontent.com/u/29852197?v=4)](https://github.com/ZachJBurns "ZachJBurns (2 commits)")[![atielking](https://avatars.githubusercontent.com/u/11356462?v=4)](https://github.com/atielking "atielking (2 commits)")[![Pplum09](https://avatars.githubusercontent.com/u/10876661?v=4)](https://github.com/Pplum09 "Pplum09 (1 commits)")[![ryangreenberg](https://avatars.githubusercontent.com/u/134712?v=4)](https://github.com/ryangreenberg "ryangreenberg (1 commits)")[![sarahhenkens](https://avatars.githubusercontent.com/u/144886?v=4)](https://github.com/sarahhenkens "sarahhenkens (1 commits)")[![scobb](https://avatars.githubusercontent.com/u/5445741?v=4)](https://github.com/scobb "scobb (1 commits)")[![chaseajen](https://avatars.githubusercontent.com/u/12056866?v=4)](https://github.com/chaseajen "chaseajen (1 commits)")[![bar](https://avatars.githubusercontent.com/u/88155?v=4)](https://github.com/bar "bar (1 commits)")[![traviscrawford](https://avatars.githubusercontent.com/u/112258?v=4)](https://github.com/traviscrawford "traviscrawford (1 commits)")[![yucombinator](https://avatars.githubusercontent.com/u/3333944?v=4)](https://github.com/yucombinator "yucombinator (1 commits)")[![azjezz](https://avatars.githubusercontent.com/u/29315886?v=4)](https://github.com/azjezz "azjezz (1 commits)")

### Embed Badge

![Health badge](/badges/slack-hack-json-schema/health.svg)

```
[![Health](https://phpackages.com/badges/slack-hack-json-schema/health.svg)](https://phpackages.com/packages/slack-hack-json-schema)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
