
Product
Introducing Repository Access Permissions and Custom Roles
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.
@cerios/cerios-builder
Advanced tools
A TypeScript builder pattern library providing compile-time type safety for object construction with method chaining and required field validation
A powerful TypeScript builder pattern library that provides compile-time type safety for object construction. Build complex objects with method chaining while ensuring all required properties are set at compile time.
npm install @cerios/cerios-builder
dev install
npm install --save-dev @cerios/cerios-builder
import { CeriosBuilder, RequiredFieldsTemplate } from '@cerios/cerios-builder';
// 1. Define your types
type User = {
id: string;
name: string;
email: string;
age?: number;
};
// 2. Create your builder
class UserBuilder extends CeriosBuilder<User> {
static create() {
return new UserBuilder({});
}
id(value: string) {
return this.setProperty('id', value);
}
name(value: string) {
return this.setProperty('name', value);
}
email(value: string) {
return this.setProperty('email', value);
}
age(value: number) {
return this.setProperty('age', value);
}
}
// 3. Build your object
const user = UserBuilder.create()
.id('123')
.name('John Doe')
.email('john@example.com')
.age(30)
.build();
| Feature | Method | Use Case |
|---|---|---|
| Simple Properties | setProperty() | Set flat object properties |
| Nested Properties | setNestedProperty() | Set deeply nested properties with dot notation |
| Array Properties | addToArrayProperty() | Add values to array properties |
| Multiple Properties | setProperties() | Set multiple properties at once |
| Required Template | static requiredTemplate | Define required fields for runtime validation |
| Dynamic Requirements | setRequiredFields() | Add required fields at runtime |
| Full Validation | build() | Build with both compile-time and runtime validation |
| Compile-Time Only | buildWithoutRuntimeValidation() | Build with TypeScript checking only |
| Runtime Only | buildWithoutCompileTimeValidation() | Build with runtime validation only |
| No Validation | buildUnsafe() | Build without any validation |
| Partial Build | buildPartial() | Build incomplete objects |
import { CeriosBuilder } from '@cerios/cerios-builder';
// Define your data type
type User = {
id: string;
name: string;
email: string;
age?: number; // Optional property
roles?: string[]; // Optional array property
};
// Create your builder class
class UserBuilder extends CeriosBuilder<User> {
static create() {
return new UserBuilder({});
}
id(value: string) {
return this.setProperty('id', value);
}
name(value: string) {
return this.setProperty('name', value);
}
email(value: string) {
return this.setProperty('email', value);
}
age(value: number) {
return this.setProperty('age', value);
}
addRole(role: string) {
return this.addToArrayProperty('roles', role);
}
// Custom methods for common patterns
withRandomId() {
return this.setProperty('id', crypto.randomUUID());
}
withAdminEmail(username: string) {
return this.setProperty('email', `${username}@admin.company.com`);
}
}
// โ
This compiles - all required fields are set
const user = UserBuilder.create()
.id("123")
.name("John Doe")
.email("john@example.com")
.age(30)
.addRole("admin")
.addRole("editor")
.build();
// โ
Optional fields and arrays can be omitted
const basicUser = UserBuilder.create()
.id("456")
.name("Jane Doe")
.email("jane@example.com")
.build(); // age and roles are optional
// โ This won't compile - missing required 'email' field
const incompleteUser = UserBuilder.create()
.id("789")
.name("Bob Smith")
.build(); // ๐ฅ TypeScript error!
const adminUser = UserBuilder.create()
.withRandomId()
.name("Admin User")
.withAdminEmail("admin")
.addRole("admin")
.age(25)
.build();
console.log(adminUser);
// Output: { id: "550e8400-...", name: "Admin User", email: "admin@admin.company.com", roles: ["admin"], age: 25 }
Build complex nested structures with type-safe dot-notation paths:
import { CeriosBuilder, RequiredFieldsTemplate } from '@cerios/cerios-builder';
type Address = {
Street: string;
City: string;
PostalCode?: string;
Country: string;
};
type OrderDetails = {
OrderNumber?: string;
CustomerId: string;
TotalAmount: number;
Status: string;
ShippingAddress: Address;
};
type Order = {
Details?: OrderDetails;
};
type OrderRequest = {
Order: Order;
};
class OrderRequestBuilder extends CeriosBuilder<OrderRequest> {
static requiredTemplate: RequiredFieldsTemplate<OrderRequest> = [
'Order.Details.CustomerId',
'Order.Details.TotalAmount',
'Order.Details.Status',
'Order.Details.ShippingAddress.Street',
'Order.Details.ShippingAddress.City',
'Order.Details.ShippingAddress.Country',
];
static create() {
return new OrderRequestBuilder({});
}
static createWithDefaults() {
return this.create().status('pending');
}
orderNumber(value: string) {
return this.setNestedProperty('Order.Details.OrderNumber', value);
}
customerId(value: string) {
return this.setNestedProperty('Order.Details.CustomerId', value);
}
totalAmount(value: number) {
return this.setNestedProperty('Order.Details.TotalAmount', value);
}
status(value: string) {
return this.setNestedProperty('Order.Details.Status', value);
}
shippingStreet(value: string) {
return this.setNestedProperty('Order.Details.ShippingAddress.Street', value);
}
shippingCity(value: string) {
return this.setNestedProperty('Order.Details.ShippingAddress.City', value);
}
shippingPostalCode(value: string) {
return this.setNestedProperty('Order.Details.ShippingAddress.PostalCode', value);
}
shippingCountry(value: string) {
return this.setNestedProperty('Order.Details.ShippingAddress.Country', value);
}
}
// Usage with full validation (both compile-time and runtime)
const order = OrderRequestBuilder.createWithDefaults()
.customerId('CUST-001')
.totalAmount(299.99)
.orderNumber('ORD-12345')
.shippingStreet('123 Main St')
.shippingCity('New York')
.shippingCountry('USA')
.build(); // โ
TypeScript + runtime validation
// โ This will throw an error at runtime
try {
const invalidOrder = OrderRequestBuilder.createWithDefaults()
.customerId('CUST-002')
.buildWithoutCompileTimeValidation(); // Missing TotalAmount and shipping address
} catch (error) {
console.error(error.message);
// "Missing required fields: Order.Details.TotalAmount, Order.Details.ShippingAddress.Street, ..."
}
Define which fields are required and validate them at runtime:
type Product = {
id: string;
name: string;
price: number;
description?: string;
};
class ProductBuilder extends CeriosBuilder<Product> {
static requiredTemplate: RequiredFieldsTemplate<Product> = [
'id',
'name',
'price',
];
static create() {
return new ProductBuilder({});
}
id(value: string) {
return this.setProperty('id', value);
}
name(value: string) {
return this.setProperty('name', value);
}
price(value: number) {
return this.setProperty('price', value);
}
description(value: string) {
return this.setProperty('description', value);
}
}
// Full validation (compile-time + runtime)
const product = ProductBuilder.create()
.id('PROD-001')
.name('Laptop')
.price(999.99)
.build(); // โ
All required fields are set
// Runtime-only validation (useful for dynamic data)
const dynamicProduct = ProductBuilder.create()
.id('PROD-002')
.name('Mouse')
.price(29.99)
.buildWithoutCompileTimeValidation(); // โ
Runtime check passes
// โ This will throw an error at runtime
try {
const invalidProduct = ProductBuilder.create()
.id('PROD-003')
.name('Keyboard')
.buildWithoutCompileTimeValidation(); // Missing price
} catch (error) {
console.error(error.message);
// "Missing required fields: price"
}
Add required fields at runtime based on business logic:
type Employee = {
firstName: string;
lastName: string;
email: string;
employeeId?: string;
phone?: string;
};
class EmployeeBuilder extends CeriosBuilder<Employee> {
static requiredTemplate: RequiredFieldsTemplate<Employee> = [
'firstName',
'lastName',
'email',
];
static create() {
return new EmployeeBuilder({});
}
firstName(value: string) {
return this.setProperty('firstName', value);
}
lastName(value: string) {
return this.setProperty('lastName', value);
}
email(value: string) {
return this.setProperty('email', value);
}
employeeId(value: string) {
return this.setProperty('employeeId', value);
}
phone(value: string) {
return this.setProperty('phone', value);
}
}
// Scenario 1: New employee (only basic fields required)
const newEmployee = EmployeeBuilder.create()
.firstName('John')
.lastName('Doe')
.email('john.doe@company.com')
.build(); // โ
Only validates firstName, lastName, email
// Scenario 2: Existing employee (ID required)
const existingEmployee = EmployeeBuilder.create()
.setRequiredFields(['employeeId']) // Add employeeId as required dynamically
.firstName('Jane')
.lastName('Smith')
.email('jane.smith@company.com')
.employeeId('EMP-12345')
.buildWithoutCompileTimeValidation(); // โ
Runtime validates all fields including employeeId
// Scenario 3: Employee with contact requirement
const contactEmployee = EmployeeBuilder.create()
.setRequiredFields(['phone', 'employeeId']) // Add multiple dynamic fields
.firstName('Bob')
.lastName('Johnson')
.email('bob.johnson@company.com')
.phone('+1-555-0123')
.employeeId('EMP-67890')
.buildWithoutCompileTimeValidation(); // โ
Validates all including phone and employeeId
// โ This will fail - missing dynamically required field
try {
const invalidEmployee = EmployeeBuilder.create()
.setRequiredFields(['employeeId'])
.firstName('Alice')
.lastName('Brown')
.email('alice.brown@company.com')
.buildWithoutCompileTimeValidation(); // Missing employeeId
} catch (error) {
console.error(error.message);
// "Missing required fields: employeeId"
}
When working with deeply nested structures, you have multiple approaches to configure required field validation:
type Address = {
Street: string;
City: string;
Country: string;
};
type OrderDetails = {
CustomerId: string;
TotalAmount: number;
ShippingAddress: Address;
};
type Order = {
Details: OrderDetails;
};
class OrderBuilder extends CeriosBuilder<Order> {
// Method 1: Static template defined at class level
static requiredTemplate: RequiredFieldsTemplate<Order> = [
'Details.CustomerId',
'Details.TotalAmount',
'Details.ShippingAddress.Street',
'Details.ShippingAddress.City',
'Details.ShippingAddress.Country',
];
static create() {
return new OrderBuilder({});
}
customerId(value: string) {
return this.setNestedProperty('Details.CustomerId', value);
}
totalAmount(value: number) {
return this.setNestedProperty('Details.TotalAmount', value);
}
shippingStreet(value: string) {
return this.setNestedProperty('Details.ShippingAddress.Street', value);
}
shippingCity(value: string) {
return this.setNestedProperty('Details.ShippingAddress.City', value);
}
shippingCountry(value: string) {
return this.setNestedProperty('Details.ShippingAddress.Country', value);
}
}
// Usage: Runtime validation checks all required fields
const order = OrderBuilder.create()
.customerId('CUST-001')
.totalAmount(299.99)
.shippingStreet('123 Main St')
.shippingCity('New York')
.shippingCountry('USA')
.buildWithoutCompileTimeValidation(); // โ
Validates all 5 required nested fields
setRequiredFields() (Best for Conditional Logic)class OrderBuilder extends CeriosBuilder<Order> {
static requiredTemplate: RequiredFieldsTemplate<Order> = [
'Details.CustomerId',
'Details.TotalAmount',
];
static create() {
return new OrderBuilder({});
}
static createInternational() {
return this.create()
.setRequiredFields([
'Details.ShippingAddress.Street',
'Details.ShippingAddress.City',
'Details.ShippingAddress.Country',
'Details.ShippingAddress.PostalCode', // Extra requirement for international
]);
}
static createDomestic() {
return this.create()
.setRequiredFields([
'Details.ShippingAddress.Street',
'Details.ShippingAddress.City',
'Details.ShippingAddress.Country',
]); // No postal code required
}
customerId(value: string) {
return this.setNestedProperty('Details.CustomerId', value);
}
totalAmount(value: number) {
return this.setNestedProperty('Details.TotalAmount', value);
}
shippingStreet(value: string) {
return this.setNestedProperty('Details.ShippingAddress.Street', value);
}
shippingCity(value: string) {
return this.setNestedProperty('Details.ShippingAddress.City', value);
}
shippingCountry(value: string) {
return this.setNestedProperty('Details.ShippingAddress.Country', value);
}
shippingPostalCode(value: string) {
return this.setNestedProperty('Details.ShippingAddress.PostalCode', value);
}
}
// Domestic order: postal code is optional
const domesticOrder = OrderBuilder.createDomestic()
.customerId('CUST-001')
.totalAmount(99.99)
.shippingStreet('123 Main St')
.shippingCity('New York')
.shippingCountry('USA')
.buildWithoutCompileTimeValidation(); // โ
Valid without postal code
// International order: postal code is required
const internationalOrder = OrderBuilder.createInternational()
.customerId('CUST-002')
.totalAmount(299.99)
.shippingStreet('10 Downing Street')
.shippingCity('London')
.shippingCountry('UK')
.shippingPostalCode('SW1A 2AA')
.buildWithoutCompileTimeValidation(); // โ
All fields including postal code validated
// โ This will fail - missing postal code for international
try {
const invalidOrder = OrderBuilder.createInternational()
.customerId('CUST-003')
.totalAmount(150.00)
.shippingStreet('Rue de Rivoli')
.shippingCity('Paris')
.shippingCountry('France')
.buildWithoutCompileTimeValidation(); // Missing PostalCode
} catch (error) {
console.error(error.message);
// "Missing required fields: Details.ShippingAddress.PostalCode"
}
Perfect for creating test fixtures with sensible defaults:
type Product = {
name: string;
price: number;
category: string;
tags?: string[];
};
class ProductBuilder extends CeriosBuilder<Product> {
static create() {
return new ProductBuilder({});
}
name(value: string) {
return this.setProperty('name', value);
}
price(value: number) {
return this.setProperty('price', value);
}
category(value: string) {
return this.setProperty('category', value);
}
addTag(tag: string) {
return this.addToArrayProperty('tags', tag);
}
// Custom methods for testing
asElectronics() {
return this.category('Electronics').price(299.99);
}
asFreeProduct() {
return this.price(0);
}
withRandomName() {
const names = ['Widget', 'Gadget', 'Tool', 'Device'];
return this.name(names[Math.floor(Math.random() * names.length)]);
}
}
// In your tests
const testProduct = ProductBuilder.create()
.withRandomName()
.asElectronics()
.addTag("featured")
.addTag("sale")
.build();
type Address = {
street: string;
city: string;
country: string;
zipCode?: string;
};
type Customer = {
id: string;
name: string;
address: Address;
phoneNumber?: string;
notes?: string[];
};
class AddressBuilder extends CeriosBuilder<Address> {
static create() {
return new AddressBuilder({});
}
static createWithDefaults() {
return this.create().setProperties({
city: "Othertown",
country: "United States",
});
}
street(value: string) {
return this.setProperty('street', value);
}
city(value: string) {
return this.setProperty('city', value);
}
country(value: string) {
return this.setProperty('country', value);
}
zipCode(value: string) {
return this.setProperty('zipCode', value);
}
asUSAddress() {
return this.country('United States');
}
}
class CustomerBuilder extends CeriosBuilder<Customer> {
static create() {
return new CustomerBuilder({});
}
id(value: string) {
return this.setProperty('id', value);
}
name(value: string) {
return this.setProperty('name', value);
}
address(value: Address) {
return this.setProperty('address', value);
}
phoneNumber(value: string) {
return this.setProperty('phoneNumber', value);
}
addNote(note: string) {
return this.addToArrayProperty('notes', note);
}
withAddress(builderFn: (builder: AddressBuilder) => AddressBuilder & CeriosBrand<Address>) {
const address = builderFn(AddressBuilder.create()).build();
return this.setProperty('address', address);
}
withAddressDefaults(
builderFn: (
builder: AddressBuilder & CeriosBrand<Pick<Address, "city" | "country">>
) => AddressBuilder & CeriosBrand<Address>
) {
const address = builderFn(AddressBuilder.createWithDefaults()).build();
return this.setProperty('address', address);
}
}
// Usage with full address
const customer = CustomerBuilder.create()
.id('CUST-001')
.name('Alice Johnson')
.withAddress(addr => addr
.street('123 Main St')
.city('New York')
.asUSAddress()
.zipCode('10001')
)
.addNote("VIP customer")
.addNote("Prefers email contact")
.phoneNumber('+1-555-0123')
.build();
// Usage with defaults
const customerWithDefaults = CustomerBuilder.create()
.id('CUST-002')
.name('Bob Smith')
.withAddressDefaults(addr => addr.street('456 Elm St'))
.addNote("New customer")
.build();
console.log(customerWithDefaults);
// Output: { id: 'CUST-002', name: 'Bob Smith', address: { street: '456 Elm St', city: 'Othertown', country: 'United States' }, notes: ['New customer'] }
Sometimes you need to build incomplete objects:
// Build partial objects when not all data is available
const partialUser = UserBuilder.create()
.name("Unknown User")
.addRole("guest")
.buildPartial(); // Returns Partial<User>
// This is useful for:
// - Progressive form filling
// - API responses with optional fields
// - Template objects
Cerios Builder is perfect for test data creation:
describe('User Service', () => {
test('should create user with valid data', () => {
const userData = UserBuilder.create()
.withRandomId()
.name('Test User')
.email('test@example.com')
.addRole('tester')
.age(25)
.build();
const result = userService.createUser(userData);
expect(result.success).toBe(true);
expect(result.user.name).toBe('Test User');
expect(result.user.roles).toContain('tester');
});
test('should handle users without age', () => {
const userData = UserBuilder.create()
.withRandomId()
.name('Ageless User')
.email('ageless@example.com')
.addRole('guest')
.build();
const result = userService.createUser(userData);
expect(result.success).toBe(true);
expect(result.user.age).toBeUndefined();
expect(result.user.roles).toContain('guest');
});
});
// โ No compile-time safety
const order = {
Order: {
Details: {
CustomerId: "CUST-001",
TotalAmount: 299.99,
// Oops! Forgot required Status field
ShippingAddress: {
Street: "123 Main St",
// Oops! Forgot required City and Country
}
}
}
};
// โ Runtime error waiting to happen
orderService.createOrder(order);
// โ
Type-safe nested property building
const order = OrderRequestBuilder.createWithDefaults()
.customerId('CUST-001')
.totalAmount(299.99)
.shippingStreet('123 Main St')
.shippingCity('New York')
.shippingCountry('USA')
.build(); // โ
Both compile-time and runtime validation
// โ
Clear error messages at runtime
try {
const invalid = OrderRequestBuilder.createWithDefaults()
.customerId('CUST-002')
.buildWithoutCompileTimeValidation();
} catch (error) {
console.error(error.message);
// "Missing required fields: Order.Details.TotalAmount,
// Order.Details.ShippingAddress.Street, ..."
}
Base class for all builders.
requiredTemplate?: RequiredFieldsTemplate<T> - Optional array of required field paths for runtime validationsetProperty<K>(key: K, value: T[K]) - Sets a property and returns a new builder instancesetProperties<K>(props: Pick<T, K>) - Sets multiple properties at once and returns a new builder instancesetNestedProperty<P>(path: P, value: PathValue<T, P>) - Sets a deeply nested property using dot notationaddToArrayProperty<K, V>(key: K, value: V) - Adds a value to an array property and returns a new builder instancesetRequiredFields(fields: ReadonlyArray<Path<T>>) - Sets required fields dynamically for this instancebuild() - Builds with both compile-time and runtime validation (recommended)
requiredTemplatebuildWithoutRuntimeValidation() - Builds with compile-time validation only
buildWithoutCompileTimeValidation() - Builds with runtime validation only
requiredTemplatebuildUnsafe() - Builds without any validation
buildPartial() - Builds a partial object
Partial<T> with currently set propertiesType-safe array of paths for defining required fields.
type RequiredFieldsTemplate<T> = ReadonlyArray<Path<T>>;
Example:
static requiredTemplate: RequiredFieldsTemplate<OrderRequest> = [
'Order.Details.CustomerId',
'Order.Details.TotalAmount',
'Order.Details.ShippingAddress.Street',
];
Type utility that generates all valid dot-notation paths for a type.
// For a type like:
type User = {
profile: {
name: string;
email: string;
};
};
// Path<User> includes:
// 'profile' | 'profile.name' | 'profile.email'
Type utility that tracks which properties have been set at the type level.
build() - Full Validation (Recommended)Use build() when you want both compile-time and runtime validation. This is the safest option.
class UserBuilder extends CeriosBuilder<User> {
static requiredTemplate: RequiredFieldsTemplate<User> = ['id', 'name', 'email'];
// ... methods
}
const user = UserBuilder.create()
.id('123')
.name('John')
.email('john@example.com')
.build(); // โ
TypeScript + runtime validation
// โ TypeScript error - missing email
const invalid1 = UserBuilder.create()
.id('123')
.name('John')
.build();
// โ Runtime error - missing email
try {
const invalid2 = UserBuilder.create()
.id('123')
.name('John')
.build();
} catch (error) {
console.error(error.message); // "Missing required fields: email"
}
Use when:
buildWithoutRuntimeValidation() - Compile-Time OnlyUse when you want TypeScript safety but need to skip runtime validation for performance.
const user = UserBuilder.create()
.id('123')
.name('John')
.email('john@example.com')
.buildWithoutRuntimeValidation(); // โ
Fast build, no runtime check
// โ Still won't compile - TypeScript enforces types
const invalid = UserBuilder.create()
.id('123')
.name('John')
.buildWithoutRuntimeValidation();
Use when:
buildWithoutCompileTimeValidation() - Runtime OnlyUse when building from external data where compile-time checks aren't possible.
function buildFromAPI(data: any) {
const builder = UserBuilder.create();
if (data.id) builder = builder.id(data.id);
if (data.name) builder = builder.name(data.name);
if (data.email) builder = builder.email(data.email);
return builder.buildWithoutCompileTimeValidation(); // Runtime validation
}
// โ
Valid data passes
const user = buildFromAPI({ id: '123', name: 'John', email: 'john@example.com' });
// โ Invalid data throws
try {
const invalid = buildFromAPI({ id: '123', name: 'John' }); // Missing email
} catch (error) {
console.error(error.message); // "Missing required fields: email"
}
Use when:
buildUnsafe() - No ValidationUse only when you're certain the object is valid and need maximum performance.
const user = UserBuilder.create()
.id('123')
.buildUnsafe(); // โ ๏ธ No checks at all
console.log(user); // { id: '123' } - potentially incomplete!
Use when:
buildPartial() - Partial ObjectsUse when you need incomplete objects.
const partial = UserBuilder.create()
.name('Incomplete User')
.buildPartial(); // Returns Partial<User>
console.log(partial); // { name: 'Incomplete User' }
Use when:
| Method | Compile-Time Check | Runtime Check | Performance | Safety | Use Case |
|---|---|---|---|---|---|
build() | โ | โ | Medium | Highest | Production code |
buildWithoutRuntimeValidation() | โ | โ | Fast | High | Performance-critical |
buildWithoutCompileTimeValidation() | โ | โ | Medium | Medium | External data |
buildUnsafe() | โ | โ | Fastest | Lowest | Trusted scenarios only |
buildPartial() | โ | โ | Fast | N/A | Incomplete objects |
Use setNestedProperty() for deep structures: Instead of building nested objects separately, use dot notation for better type safety and cleaner code.
Define requiredTemplate for runtime validation: When working with external data or complex validation rules, define a required template.
Choose the right build method:
build() for safetybuildWithoutRuntimeValidation() for performancebuildWithoutCompileTimeValidation() for external databuildUnsafe() only when absolutely necessaryUse setRequiredFields() for conditional requirements: When requirements change based on context (e.g., new vs existing records), use dynamic required fields.
Create factory methods: Use static create() and createWithDefaults() methods for better ergonomics:
static createWithDefaults() {
return this.create()
.status('pending')
.createdAt(new Date());
}
Combine with validation libraries: Use runtime validation with libraries like Zod for comprehensive validation:
const data = builder.buildWithoutCompileTimeValidation();
const validated = orderSchema.parse(data); // Zod validation
Keep builders focused: One builder per entity type - don't try to handle multiple unrelated types in one builder.
Use type-safe paths: The RequiredFieldsTemplate type ensures you can only specify valid paths:
static requiredTemplate: RequiredFieldsTemplate<Order> = [
'Details.CustomerId', // โ
Valid path
'Details.InvalidField', // โ TypeScript error
];
MIT ยฉ Cerios
FAQs
A TypeScript builder pattern library providing compile-time type safety for object construction with method chaining and required field validation
The npm package @cerios/cerios-builder receives a total of 20 weekly downloads. As such, @cerios/cerios-builder popularity was classified as not popular.
We found that @cerios/cerios-builder demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.ย It has 2 open source maintainers 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.

Product
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.

Product
Socket Firewall blocks malicious VS Code and Open VSX extensions before install, protecting developers from compromised editor marketplaces.