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

gymmonk-schema

v0.1.3

Published

Shared Zod domain schemas for Gym SaaS (frontend + backend).

Readme

🏋️ gymmonk-schema

Central Zod v4 schema library for the GymMonk / Gym SaaS ecosystem.

npm version License


📋 Table of Contents


🎯 Overview

This package is the single source of truth for:

  • ✅ Domain models (User, Organisation, Center, Membership, Workout, etc.)
  • ✅ API DTOs (create/update payloads)
  • ✅ Public view models (safe objects to send to frontend)
  • ✅ Shared primitives (ObjectId, dates, pagination, etc.)

🚀 Designed for Multi-Platform Use

It is designed to be used by:

  • Backend (Node.js / Express)
  • Web frontend (Next.js)
  • Mobile app (React Native)
  • API-doc project (OpenAPI/Swagger via zod-to-openapi)

So all layers share the same contracts.


📦 Installation

In any consumer project (backend, web, app, api-doc):

npm install gymmonk-schema
# or
yarn add gymmonk-schema
# or
pnpm add gymmonk-schema

💡 Core Concepts

Schemas vs Types

Each entity is represented by a Zod schema and a corresponding TypeScript type:

import { z } from "zod";

export const RoleSchema = z.object({
  name: z.string().min(1),
  description: z.string().trim().optional(),
  permissions: z.array(z.string()).default([]),
});

export type Role = z.infer<typeof RoleSchema>;

Two Different Layers

| Layer | Description | | ------------------------- | ------------------------------------------------------------------------------------------------------------------ | | Schema (RoleSchema) | • Real runtime object• Validates and parses data• Used in controllers, services, forms, API-doc generation | | Type (Role) | • Compile-time only (erased at runtime)• Used by TypeScript for static checking and autocomplete |

You will see this pattern throughout the library.

Naming Conventions

Inside each domain:

  • Schemas are named: XxxSchema
  • Types are named: Xxx (via z.infer<typeof XxxSchema>)
  • DTOs (request/response payloads) are named: XxxCreateDtoSchema, XxxUpdateDtoSchema, etc.
  • Public view models (safe to send to frontend): PublicXxxSchema, type PublicXxx

🏗️ Library Structure

At the top level, the package exposes namespaced domains:

import {
  Common,
  Auth,
  Gym,
  Workout,
  Nutrition,
  Subscription,
  Marketing,
  Notification,
  Community,
  Feedback,
  Support,
  Landing,
  Audit,
} from "gymmonk-schema";

Each domain has its own folder + barrel file and follows the same structure: schemas + types grouped by feature.

Below is an overview of what each domain represents.


🔧 Common

Building blocks used everywhere.

Includes:

Primitives

  • ObjectIdSchema
  • IsoDateStringSchema
  • IsoDateTimeStringSchema
  • NonEmptyStringSchema, OptionalStringSchema, etc.

Value Objects

  • EmailSchema
  • PhoneSchema
  • AddressSchema
  • NutritionalValuesSchema
  • PlanVariantSchema (for flexible pricing options)
  • MfaSchema, SocialLoginSchema, etc.

Enums

  • Gender enum
  • EntityStatus enum
  • NotificationType enum

Pagination

  • PaginationSchema (common page, limit, etc.)

Usage Example

const id = Common.Primitives.ObjectIdSchema.parse(someString);
const pagination = Common.Pagination.PaginationSchema.parse(req.query);

ℹ️ Exact nested names may vary slightly; check src/common/index.ts for the authoritative exports.


🔐 Auth

Authentication & authorization related models.

Includes (names representative):

  • UserSchema, PublicUserSchema, UserRegisterDtoSchema etc.
  • RoleSchema (RBAC roles)
  • PermissionSchema (fine-grained permissions)
  • ResourceSchema (RBAC resources)
  • TokenSchema (access/refresh tokens, device tokens)
  • OtpSchema (one-time passwords)
  • DeviceSchema
  • PasswordHistorySchema
  • UserActivitySchema (login, logout, etc.)

Common Usage:

  • Backend: validate incoming auth requests (register, login, password reset)
  • Frontend: type-safe forms for login/register, and PublicUser types for UI

🏢 Gym

All gym/organisation/center management models.

Includes:

Organisation / Centers

  • OrganisationSchema
  • CenterSchema
  • CenterFacilitySchema
  • CenterServiceSchema

Catalogs

  • EquipmentCatalogSchema
  • FacilityCatalogSchema
  • ServiceCatalogSchema

Operational Models

  • AttendanceSchema
  • ClassScheduleSchema
  • EquipmentInventorySchema
  • GymLayoutSchema
  • SessionBookingSchema
  • GoalSchema
  • AchievementBadgeSchema

Used to Define and Validate:

  • How the gym, centers, facilities, services are modeled
  • Attendance tracking
  • Booking / layout / goals / badges

💪 Workout

Exercise and workout planning & tracking.

Includes:

  • ExerciseSchema (name, muscle groups, media, equipment)
  • WorkoutPlanSchema (list of exercises with sets/reps/duration)
  • WorkoutTrackingEntrySchema (what a member actually did, per set, per day)

Used By:

  • Backend: workout CRUD, tracking endpoints
  • Frontend/App: typed workout UI, tracking screens

🥗 Nutrition

Ingredient, recipes, diet plans, hydration.

Includes:

  • IngredientSchema
  • RecipeSchema, RecipeIngredientSchema
  • DietPlanSchema, DietPlanMealSchema, DietPlanItemSchema
  • DietTrackingEntrySchema
  • HydrationTrackingSchema

Use This For:

  • Building diet plans and logging diets
  • Aggregating nutrition
  • Hydration tracking

💳 Subscription

Subscription, membership, coupons, payments.

Includes:

  • SubscriptionPlanSchema
  • SubscriptionSchema
  • MembershipPlanSchema
  • MembershipSchema
  • CouponSchema
  • PaymentTransactionSchema

Used For:

  • Defining product plans and membership plans
  • Linking members to plans (Membership, Subscription)
  • Applying coupons and tracking payments

📢 Marketing

Branding, ads, campaigns, referrals.

Includes:

  • BrandSchema
  • AdvertisementSchema
  • MarketingCampaignSchema
  • ReferralSchema

Used For:

  • Dashboard banners, campaigns, referral systems
  • Representing marketing data in a unified way

🔔 Notification

Notifications and templates.

Includes:

  • NotificationSchema (delivered notification entries)
  • NotificationTemplateSchema (reusable templates per channel)

Supports channels like: in_app, push, email, sms.


👥 Community

Internal community / communication layer.

Includes:

  • ConversationSchema
  • MessageSchema
  • PostSchema

Used For:

  • Chats
  • Group conversations
  • Community posts

💬 Feedback

User feedback, bug reports, ratings.

Includes:

  • FeedbackSchema (type, message, metadata, rating)

🎫 Support

Support tickets.

Includes:

  • SupportTicketSchema (priority, status, category, assignments, metadata)

🌐 Landing

Contact requests from marketing/landing pages.

Includes:

  • ContactRequestSchema (name, email/phone, subject, message, metadata)

📝 Audit

Audit logs.

Includes:

  • AuditLogSchema (who, what, when, before/after, metadata)

📥 How to Import

Top-Level Domains (Recommended)

Prefer importing from the root in most cases:

import {
  Auth,
  Gym,
  Subscription,
  Workout,
  Nutrition,
  Common,
} from "gymmonk-schema";

// Auth
const dto = Auth.UserRegisterDtoSchema.parse(body);

// Gym
const center = Gym.CenterSchema.parse(payload);

// Subscription
type Plan = Subscription.SubscriptionPlan;
const planSchema = Subscription.SubscriptionPlanSchema;

💡 If you want very fine-grained imports, you can also import directly from subpaths as long as your build/exports are configured for it (check your package.json "exports" if you add that later).


🎨 Usage Examples

Backend (Express)

Validate Request Body (DTO)

import { Auth } from "gymmonk-schema";
import type { Request, Response } from "express";

export async function registerHandler(req: Request, res: Response) {
  try {
    const dto = Auth.UserRegisterDtoSchema.parse(req.body);

    // dto is fully validated and typed
    const user = await createUser(dto);

    const publicUser = Auth.PublicUserSchema.parse(user);
    return res.status(201).json(publicUser);
  } catch (err: any) {
    return res.status(400).json({
      message: "Invalid request",
      errors: err.errors ?? err,
    });
  }
}

Validate Query Params

import { Common } from "gymmonk-schema";

app.get("/centers", (req, res) => {
  const pagination = Common.Pagination.PaginationSchema.parse(req.query);
  // use pagination.page / pagination.limit
});

Frontend (Next.js)

Validate Data Before Sending to Backend

"use client";

import { Auth } from "gymmonk-schema";

async function submit(formData: any) {
  const dto = Auth.UserRegisterDtoSchema.parse(formData);

  const res = await fetch("/api/auth/register", {
    method: "POST",
    body: JSON.stringify(dto),
    headers: { "Content-Type": "application/json" },
  });

  return res.json();
}

Strongly Typed UI Components

import { Gym } from "gymmonk-schema";

type Center = Gym.Center;

function CenterCard({ center }: { center: Center }) {
  return (
    <div>
      <h2>{center.name}</h2>
      <p>{center.address?.city}</p>
    </div>
  );
}

Forms (React Hook Form + Zod)

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Subscription } from "gymmonk-schema";

const schema = Subscription.SubscriptionPlanSchema;
type PlanForm = Subscription.SubscriptionPlan;

export function PlanFormComponent() {
  const form = useForm<PlanForm>({
    resolver: zodResolver(schema),
  });

  // form.register, form.handleSubmit, etc.
}

API-doc / OpenAPI

In your API-doc project (contract-first design), you can introspect schemas and generate OpenAPI:

import {
  OpenAPIRegistry,
  generateOpenApiDocument,
} from "@asteasolutions/zod-to-openapi";
import { Auth, Gym } from "gymmonk-schema";

const registry = new OpenAPIRegistry();

// Register schemas
registry.register("User", Auth.PublicUserSchema);
registry.register("Center", Gym.CenterSchema);

// Register routes and use the schemas in request/response definitions…

const openapi = generateOpenApiDocument(registry.definitions, {
  openapi: "3.0.0",
  info: {
    title: "GymMonk API",
    version: "1.0.0",
  },
});

// Then write openapi.json and serve via swagger-ui-express

This way API docs are always in sync with your code and frontend types.


🛠️ Development & Publishing

In the gymmonk-schema repo:

Build

npm run build

Typical script:

"build": "tsc"

This compiles src/**/*.tsdist/**/*.js + .d.ts.

Lint + Format

Using Biome:

npm run check      # type-check + lint + format (depending on your script)
npm run lint       # if you have a separate lint script
npm run format     # if you have a separate format script

Version Bump

Use semantic versioning:

npm version patch   # 0.1.0 -> 0.1.1
npm version minor   # 0.1.0 -> 0.2.0
npm version major   # 0.1.0 -> 1.0.0

This updates package.json and creates a git commit + tag (if configured).

Publish

npm login
npm run build
npm publish --access public

Then consumers can install:

npm install gymmonk-schema

📌 Versioning

Follow standard SemVer:

| Version Type | Pattern | Description | | ------------ | ------- | ---------------------------------------------------------------- | | PATCH | x.y.Z | Internal fixes, no breaking changes | | MINOR | x.Y.z | New schemas/fields added in a backwards-compatible way | | MAJOR | X.y.z | Breaking changes (removed fields, renamed, incompatible changes) |

Guidelines:

  • Adding optional fields: minor
  • ⚠️ Making a field required or changing its type: major
  • ⚠️ Removing schemas or renaming them: major

📝 Keep a simple CHANGELOG.md to track what changed between versions, especially when schemas or DTOs change in ways that affect consumers.


Built with ❤️ for the GymMonk ecosystem