Engineers use libraries because they deliver real reusability. Instead of rewriting the same code repeatedly, teams use shared packages for logging, auth helpers, HTTP clients, validation, and database access. These libraries solve a clear need: they help developers avoid starting from scratch on routine tasks and maintain consistent behavior across projects.The desire for reuse runs deep. Once a team experiences the gains from a solid auth library or HTTP client, it’s natural to want the same benefits at a higher level - not just individual functions, but entire backend capabilities.
Moving from Functions to Complete Components
This is where Ductape comes in. Instead of reusing low-level helpers, Ductape lets you define and reuse complete backend components - databases, third-party API integrations, storage, messaging, notifications, and more - all organized under a Product. Each component includes its environments, credentials (managed as secrets), configuration, and runtime behavior. You define it once, and any codebase that initializes the SDK with the right Product and environment can use it immediately -without rewiring auth, URLs, or integration logic in every repository.
Third-Party Apps (e.g., Stripe)
You connect and configure apps through the Ductape Workbench or builder APIs, then call them cleanly from the SDK:
import Ductape from '@ductape/sdk';
const ductape = new Ductape({
accessKey: process.env.DUCTAPE_ACCESS_KEY!,
product: 'my-app',
env: 'stg',
});
// Configure credentials once (secrets resolved at runtime)
ductape.api.config({
app: 'stripe',
env: 'stg',
credentials: {
'headers:Authorization': '$Secret{STRIPE_API_KEY}',
},
});
// Run actions from any service
const charge = await ductape.api.run({
app: 'stripe',
action: 'create-charge',
input: { amount: 1000, currency: 'usd' },
});
const customer = await ductape.api.run({
app: 'stripe',
action: 'create-customer',
input: { email: 'user@example.com' },
});
OAuth flows are handled via ductape.api.oauth() when needed. The runtime code stays minimal and consistent.
Databases
The same principle applies to databases:
// Define once (usually via Workbench or builder API)
await ductape.databases.create({
product_tag: 'my-app',
tag: 'primary-db',
name: 'Primary Database',
type: 'postgresql',
envs: [
{
slug: 'stg',
connection_url: 'postgresql://staging-host:5432/myapp',
},
{
slug: 'prd',
connection_url: 'postgresql://prod-host:5432/myapp',
},
],
});
// In application code
const ductape = new Ductape({
accessKey: process.env.DUCTAPE_ACCESS_KEY!,
product: 'my-app',
env: 'prd',
});
await ductape.databases.connect({ database: 'primary-db' });
const { records } = await ductape.databases.query({
table: 'customers',
where: { status: 'active' },
limit: 50,
});
await ductape.databases.delete({
table: 'customers',
where: { id: customerId },
});
Connection pooling, retries, and logging are handled by the platform and SDK.
The Vision with Ductape
Ductape turns backend integrations and services into reusable, portable Product components. Payment processors, databases, notification channels, storage buckets, and job queues can be defined centrally per Product and environment, then consumed consistently from TypeScript, Go, Java, .NET, NestJS, or other SDKs.
Developers stay focused on product-specific logic while relying on components that already carry the correct environment configuration and credential handling. Updating a secret, changing a connection string, or adjusting configuration in the Workbench instantly reflects across all services without redeploying boilerplate code.
It’s not about importing another vendor SDK, it’s about defining your backend infrastructure and integrations once on the Product, then using them everywhere through a single, lightweight SDK. Ductape brings the same reusability and consistency that libraries provide at the function level, but now at the level of complete, production-ready backend components.
Top comments (0)