Using grabr with TanStack Start
TanStack Start is a modern, full-stack React framework powered by TanStack Router. Since grabr requires Node.js to perform aggressive file I/O and parallel chunking, we can perfectly utilize TanStack Start's createServerFn to run grabr securely on the server while triggering it from the client.
1. Create a TanStack Start Project
npx create-tsrouter-app@latest my-grabr-app
cd my-grabr-app
npm install @linuxctrl/grabr2. Build the Server Function
Create a file at app/server/download.ts:
import { createServerFn } from '@tanstack/start'
import { Downloader } from '@linuxctrl/grabr'
import path from 'path'
import fs from 'fs'
export const triggerDownload = createServerFn({ method: 'POST' })
.validator((data: { url: string; filename: string }) => data)
.handler(async ({ data }) => {
const { url, filename } = data
const outputDir = path.join(process.cwd(), 'downloads')
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true })
}
const downloader = new Downloader()
await downloader.start()
try {
const job = await downloader.addJob(url, {
outputDir,
filename,
chunks: 8,
})
console.log(`Started downloading ${job.filename} (ID: ${job.id})`)
return { success: true, jobId: job.id }
} catch (error) {
console.error("Download failed to start:", error)
return { success: false, error: String(error) }
}
})3. Create the Frontend UI
Open app/routes/index.tsx and replace its contents:
import { createFileRoute } from '@tanstack/react-router'
import { triggerDownload } from '../server/download'
import { useState } from 'react'
export const Route = createFileRoute('/')({
component: Home,
})
function Home() {
const [url, setUrl] = useState('https://speed.hetzner.de/100MB.bin')
const [status, setStatus] = useState('')
const handleDownload = async () => {
setStatus('Starting grabr engine...')
const result = await triggerDownload({ data: { url, filename: 'test-file.bin' } })
if (result.success) {
setStatus('Downloading! Check your terminal and the ./downloads folder.')
} else {
setStatus(`Error: ${result.error}`)
}
}
return (
<main className="p-10 max-w-xl mx-auto space-y-4 font-sans">
<h1 className="text-2xl font-bold">Grabr + TanStack Start Demo</h1>
<input
type="text"
value={url}
onChange={(e) => setUrl(e.target.value)}
className="w-full p-2 border rounded text-black"
placeholder="Enter file URL..."
/>
<button onClick={handleDownload} className="px-4 py-2 bg-cyan-500 text-white font-bold rounded hover:bg-cyan-600 transition-colors">
Download on Server
</button>
{status && <p className="text-sm font-medium mt-4">{status}</p>}
</main>
)
}4. Run the Application
npm run devOpen your browser, click "Download on Server", and watch your terminal. The TanStack Start backend will instantly begin using grabr to parallel-chunk your download at maximum speed into the ./downloads folder.