Migrate from Pinata
Why migrate?
- Decentralized infrastructure: no single point of failure, no lock-in
- Competitive pricing: pay for pinning, not bundled gateway infrastructure
- Privacy-focused: your data, your control
- Compatibility adapter: swap the SDK, keep most of your call patterns
Migration strategy
| Approach | Best for | Effort |
|---|---|---|
| Pinata Adapter | Quick migration, minimal code changes | Low |
| Native Pinner API | Long-term projects, better features | Medium |
Feature compatibility
The adapter provides broad Pinata API coverage, but some features are not supported because Pinner's architecture differs from Pinata's:
| Feature | v2 Adapter | Legacy Adapter | Notes |
|---|---|---|---|
| Public file upload | ✅ | ✅ | file, fileArray, base64, json |
| Pin by CID | ✅ | ✅ | |
| Private uploads | ❌ | ❌ | Throws "not supported" |
| URL upload | ❌ | N/A | Throws "not supported" in v2 |
| File listing | ✅ | ✅ | Pagination filters limited |
| Get file by ID | ✅ | ✅ | |
| Delete / unpin | ✅ | ✅ | |
| Update metadata | ✅ | ✅ | |
| Pin queue | ✅ | ✅ | Returns pinned items (no true queue) |
| Groups | ⚠️ | N/A | list() returns empty; create/add/remove throw |
| Gateways | ✅ | N/A | Public gateways only; private throws |
| Signed URLs | ❌ | ⚠️ | v2 throws; legacy returns gateway URL fallback |
| Swap CID | ❌ | ❌ | Throws "not supported" |
| Analytics | ⚠️ | ⚠️ | Returns empty data (not real analytics) |
For the full adapter method reference, see Adapter Reference.
Adapter setup
Install Pinner
npm install @lumeweb/pinnerPick your adapter
Pinata SDK 2.x: use pinataAdapter:
import { Pinner, pinataAdapter } from "@lumeweb/pinner";
const pinner = new Pinner({ jwt: process.env.PINNER_AUTH_TOKEN! });
const adapter = pinataAdapter(pinner);Pinata SDK 1.x: use pinataLegacyAdapter:
import { Pinner, pinataLegacyAdapter } from "@lumeweb/pinner";
const pinner = new Pinner({ jwt: process.env.PINNER_AUTH_TOKEN! });
const adapter = pinataLegacyAdapter(pinner);Step-by-step: replace initialization
- Replace the import. Swap
pinatafor@lumeweb/pinnerand import the adapter. - Replace the constructor. Instead of
new PinataSDK({ pinataJwt }), usenew Pinner({ jwt })+ adapter. - Handle unsupported features. Remove or replace calls to private uploads, groups, swap CID, signed URLs, and URL uploads (see Feature compatibility).
- Add
.execute()to v2 builder methods. The v2 adapter uses a builder pattern: chain.name()and.keyvalues(), then call.execute(). - Test uploads and listings. Verify your existing calls work with the adapter.
Error handling
Pinner errors use a different structure. Instead of catching generic errors:
import { PinnerError } from "@lumeweb/pinner";
try {
const result = await adapter.upload.public.file(file).execute();
} catch (error) {
if (error instanceof PinnerError) {
console.error("Code:", error.code);
console.error("Message:", error.message);
console.error("Retryable:", error.retryable);
}
}PinnerError has the following properties:
| Property | Type | Description |
|---|---|---|
code | string | Machine-readable error code (e.g. "UPLOAD_ERROR", "PIN_ERROR") |
message | string | Human-readable error message |
retryable | boolean | Whether the operation can be retried |
See the Error Reference for all error codes and retry guidance.
Migration checklist
- Install
@lumeweb/pinner - Update imports and initialization
- Remove or replace unsupported features (private uploads, groups, swap CID, signed URLs, URL uploads)
- Add
.execute()to builder methods (v2 adapter only) - Test file uploads
- Test file listing and deletion
- Update error handling
- Remove Pinata SDK dependency
- Deploy and monitor
Testing your migration
- Test in development: verify all upload operations work
- Check file listings: ensure metadata is preserved
- Verify deletions: test unpin operations
- Test unsupported feature handling: confirm your app gracefully handles
notSupportederrors - Monitor performance: compare upload speeds
- Review costs: check your billing
Next steps
- Adapter Reference: full v2 and legacy adapter method docs
- Code Examples: side-by-side Pinata vs Pinner code
- SDK Getting Started: using Pinner without the adapter