
Company News
Socket Named Top Sales Organization by RepVue
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.
@chneau/typed-meteor
Advanced tools
Type-safe wrappers for Meteor methods and subscriptions using Zod schemas. Define your methods and publications once, and enjoy full type safety across client and server.
useTracker in React.npm install @chneau/typed-meteor zod
# or
bun add @chneau/typed-meteor zod
# or
yarn add @chneau/typed-meteor zod
Define your collection, schemas, methods, and subscriptions in a shared file (or server-side file if you prefer, but types must be available to client).
import { typedMethod, typedSubscribe } from "@chneau/typed-meteor";
import z from "zod";
const linkSchema = z.object({
_id: z.string().optional(),
title: z.string(),
url: z.url(),
createdAt: z.date(),
deletedAt: z.date().nullish(),
});
type Link = z.infer<typeof linkSchema>;
export const LinksCollection = new Mongo.Collection<Link>("links");
export const subscribeLinks = typedSubscribe({
name: "links",
input: z.boolean().optional(),
output: linkSchema.extend({ _id: z.string() }),
collection: LinksCollection,
fn: (showDeletedToo) => {
const query: Mongo.Query<Link> = {};
if (!showDeletedToo) {
query.$or = [{ deletedAt: { $exists: false } }, { deletedAt: null }];
}
return LinksCollection.find(query);
},
});
export const methodCreateLink = typedMethod({
name: "links.insert",
input: z.object({
title: z.string(),
url: z.url(),
}),
output: z.string(),
fn: async ({ title, url }) =>
await LinksCollection.insertAsync({ title, url, createdAt: new Date() }),
});
export const methodDeleteLink = typedMethod({
name: "links.delete",
input: z.string(),
output: z.number(),
fn: async (_id) => {
const current = await LinksCollection.findOneAsync(
{ _id },
{ fields: { deletedAt: 1 } },
);
if (current?.deletedAt) {
return await LinksCollection.updateAsync(
{ _id },
{ $set: { deletedAt: null } },
);
}
return await LinksCollection.updateAsync(
{ _id },
{ $set: { deletedAt: new Date() } },
);
},
});
export const createFor1Second = typedMethod({
name: "links.createFor1Second",
input: z.void(),
output: z.void(),
fn: async () => {
const _id = await methodCreateLink({
title: "Temporary Link",
url: "https://temporary-link.com",
});
await new Promise((resolve) => setTimeout(resolve, 1000));
await methodDeleteLink(_id);
},
});
Use the defined methods and subscriptions in your React components.
import { useTracker } from "meteor/react-meteor-data";
import { useState } from "react";
// Import from your API file
import {
createFor1Second,
methodCreateLink,
methodDeleteLink,
subscribeLinks,
} from "../api/links";
const SmallInfo = ({ children }: { children: React.ReactNode }) =>
children && (
<small style={{ color: "gray", fontFamily: "monospace" }}>{children}</small>
);
export const Info = () => {
const [showDeletedToo, setShowDeletedToo] = useState(false);
const links = useTracker(() => subscribeLinks(showDeletedToo));
const [x, setX] = useState(0);
return (
<div>
<h2>Learn Meteor!</h2>
<button type="button" onClick={() => setX(x + 1)}>
Click Me
</button>
<p>You've pressed the button {x} times.</p>
<button type="button" onClick={() => setShowDeletedToo(!showDeletedToo)}>
{showDeletedToo ? "Showing deleted links" : "Hiding deleted links"}
</button>
<h3>Links ({links.length})</h3>
<ul>
{links.map((x) => (
<li key={x._id}>
<SmallInfo>{x._id}</SmallInfo>
<a href={x.url} target="_blank">
{x.title}
</a>
<SmallInfo>({x.url})</SmallInfo>
<SmallInfo>{x.createdAt.toISOString()}</SmallInfo>
<SmallInfo>{x.deletedAt?.toISOString()}</SmallInfo>
<button
type="button"
onClick={() => methodCreateLink(x)}
style={{ fontSize: "0.5em" }}
>
Duplicate
</button>
<button
type="button"
onClick={() => methodDeleteLink(x._id)}
style={{ fontSize: "0.5em" }}
>
Delete
</button>
</li>
))}
</ul>
<button type="button" onClick={() => createFor1Second()}>
Create for 1 second
</button>
</div>
);
};
typedMethod<Input, Output>(options)Creates a type-safe Meteor method.
string - Unique name for the method.ZodSchema (optional) - Schema for argument validation.ZodSchema (optional) - Schema for return value
validation.(input) => Promise<Output> - The function implementation.Returns: An async function (input) => Promise<Output> that can be called
from the client.
typedSubscribe<Input, Output>(options)Creates a type-safe Meteor publication helper.
string - Unique name for the publication.ZodSchema (optional) - Schema for subscription arguments.ZodSchema (optional) - Schema to validate/transform the
documents returned by the collection.Mongo.Collection - The Mongo Collection instance.(input) => void | Mongo.Cursor - The publication function.Returns: A function (input) => Output[] that should be called within a
reactive context (like useTracker). It handles the subscription and returns
the data from the collection.
FAQs
Unknown package
We found that @chneau/typed-meteor demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.