Skip to main content
Search...

Installation

Get started with @gentleduck/upload in your project.

Install the Package

Choose your preferred package manager:

@gentleduck/upload
@gentleduck/upload

Or install manually:

bun add @gentleduck/upload
bun add @gentleduck/upload

npm install @gentleduck/upload

npm install @gentleduck/upload
pnpm add @gentleduck/upload
pnpm add @gentleduck/upload

Basic Setup

1. Create a Strategy Registry

Register the upload strategies your app needs:

import { createStrategyRegistry, PostStrategy, multipartStrategy } from '@gentleduck/upload/strategies'
 
const strategies = createStrategyRegistry()
strategies.set(PostStrategy())
strategies.set(multipartStrategy())
import { createStrategyRegistry, PostStrategy, multipartStrategy } from '@gentleduck/upload/strategies'
 
const strategies = createStrategyRegistry()
strategies.set(PostStrategy())
strategies.set(multipartStrategy())

2. Implement the Upload API

Your backend adapter must implement the UploadApi interface:

import type { UploadApi } from '@gentleduck/upload/core'
 
const api: UploadApi = {
  createIntent: async ({ file, purpose }) => {
    // Call your backend to create an upload intent
    const res = await fetch('/api/uploads/intent', {
      method: 'POST',
      body: JSON.stringify({ fileName: file.name, purpose }),
    })
    return res.json()
  },
  complete: async ({ fileId }) => {
    // Notify your backend that the upload finished
    const res = await fetch(`/api/uploads/${fileId}/complete`, { method: 'POST' })
    return res.json()
  },
}
import type { UploadApi } from '@gentleduck/upload/core'
 
const api: UploadApi = {
  createIntent: async ({ file, purpose }) => {
    // Call your backend to create an upload intent
    const res = await fetch('/api/uploads/intent', {
      method: 'POST',
      body: JSON.stringify({ fileName: file.name, purpose }),
    })
    return res.json()
  },
  complete: async ({ fileId }) => {
    // Notify your backend that the upload finished
    const res = await fetch(`/api/uploads/${fileId}/complete`, { method: 'POST' })
    return res.json()
  },
}

3. Create the Upload Store

import { createUploadStore } from '@gentleduck/upload/core'
 
const store = createUploadStore({
  api,
  strategies,
  config: {
    maxConcurrentUploads: 3,
    autoStart: (purpose) => purpose === 'avatar',
  },
})
import { createUploadStore } from '@gentleduck/upload/core'
 
const store = createUploadStore({
  api,
  strategies,
  config: {
    maxConcurrentUploads: 3,
    autoStart: (purpose) => purpose === 'avatar',
  },
})

4. Connect to React (Optional)

If you are using React, wrap your app with the UploadProvider:

import { UploadProvider } from '@gentleduck/upload/react'
 
function App() {
  return (
    <UploadProvider store={store}>
      <YourUploadUI />
    </UploadProvider>
  )
}
import { UploadProvider } from '@gentleduck/upload/react'
 
function App() {
  return (
    <UploadProvider store={store}>
      <YourUploadUI />
    </UploadProvider>
  )
}

Then use the useUploader hook in your components:

import { useUploader } from '@gentleduck/upload/react'
 
function UploadList() {
  const { items, dispatch } = useUploader()
 
  return (
    <div>
      <input
        type="file"
        onChange={(e) => {
          dispatch({ type: 'addFiles', files: Array.from(e.target.files!), purpose: 'doc' })
        }}
      />
      {items.map((item) => (
        <div key={item.localId}>{item.file?.name} - {item.phase}</div>
      ))}
    </div>
  )
}
import { useUploader } from '@gentleduck/upload/react'
 
function UploadList() {
  const { items, dispatch } = useUploader()
 
  return (
    <div>
      <input
        type="file"
        onChange={(e) => {
          dispatch({ type: 'addFiles', files: Array.from(e.target.files!), purpose: 'doc' })
        }}
      />
      {items.map((item) => (
        <div key={item.localId}>{item.file?.name} - {item.phase}</div>
      ))}
    </div>
  )
}

Import Paths

The package exposes three entry points:

ImportDescription
@gentleduck/upload/coreEngine, contracts, persistence, utilities
@gentleduck/upload/strategiesStrategy implementations and registry
@gentleduck/upload/reactReact provider and hooks