npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@felipeubidots/clickup-shortcut-migrator

v1.0.0

Published

Migrate tasks from ClickUp to Shortcut with full data preservation. Preserves descriptions, comments, subtasks, custom fields, and more.

Readme

ClickUp → Shortcut Task Migration Tool

A comprehensive task migration tool that transfers tasks from ClickUp to Shortcut while preserving all relevant data including descriptions, comments, subtasks, and custom fields.

Features

Complete Data Migration

  • Task names and descriptions (with inline images/videos)
  • Story points (Sprint Points custom field)
  • Status mapping (Open → Ready for Development, In Progress → In Development, Done → Done)
  • Assignees with email/username mapping
  • Tags → Labels (with auto-creation of missing labels)
  • Comments with author attribution
  • Subtasks as nested Shortcut stories
  • External link back-reference for traceability

Safety & Reliability

  • Duplicate detection (checks if task already migrated)
  • User ID mapping with fallback handling
  • Error handling per task (failures don't stop batch migrations)
  • Detailed reporting with migration status

Flexible Batch Operations

  • Migrate single tasks: node migrate.js abc123
  • Migrate multiple tasks: node migrate.js abc123 def456 ghi789
  • Automatic workflow state mapping
  • Label deduplication and creation on-demand

Quick Start

Prerequisites

  • Node.js v16+
  • Access to both ClickUp and Shortcut workspaces via Claude Code MCP tools

Installation

cd /path/to/task-migrator
npm install

Basic Usage

Migrate a single ClickUp task:

node migrate.js <clickup_task_id>

Migrate multiple tasks:

node migrate.js task_id_1 task_id_2 task_id_3

Example:

node migrate.js abc123def456 ghi789jkl012

How It Works

Phase 0: Setup (automatic, one-time per session)

The tool automatically initializes the Shortcut environment:

  • Fetches the default workflow and available states
  • Loads all Shortcut users and builds an email/username → ID map
  • Loads existing labels to avoid duplicates
📋 Phase 0: Initializing Shortcut environment...
  → Fetching default workflow...
    ✓ Workflow ID: 123456
    ✓ Available states: Ready for Development, In Development, Done
  → Fetching Shortcut users...
    ✓ 12 users loaded
  → Fetching Shortcut labels...
    ✓ 25 labels found
✅ Shortcut environment initialized

Phase 1: Read from ClickUp (per task)

Fetches complete task data:

  • Task name, description, status, assignees, tags
  • Sprint Points custom field (if present)
  • All attachments (images, videos, files)
  • All comments with author info
  • Subtasks
  • Original task URL (for back-reference)

Phase 2: Transform Data

Converts ClickUp data to Shortcut format:

  • Description: Converts to Markdown with embedded image/video links

    • Images: ![alt](url)
    • Videos: [▶ See video](url)
    • Files: [📎 filename](url)
    • Migration footer: ---\n*Migrated from ClickUp*
  • Status Mapping:

    • open → "Ready for Development"
    • in progress → "In Development"
    • done, closed → "Done"
  • Estimate: Extracts "Sprint Points" custom field → story estimate

  • Assignees: Maps ClickUp assignees to Shortcut users by email/username

  • Tags → Labels:

    • Reuses existing labels (case-insensitive)
    • Creates missing labels automatically with random colors

Phase 3: Write to Shortcut (per task)

  1. Duplicate Check: Verifies task hasn't been migrated already (by external link)
  2. Create Story: Creates main story in Shortcut with all metadata
  3. Add External Link: Links back to original ClickUp task
  4. Migrate Comments: Adds all comments with [ClickUp - Author] attribution
  5. Migrate Subtasks: Creates subtasks as nested Shortcut stories and links them

Phase 4: Report

Generates a summary table showing:

  • ClickUp ID
  • Task name
  • Shortcut story ID (if migrated)
  • Status (✅ Migrated, ⚠️ Skipped, ❌ Failed)

Example output:

📊 MIGRATION REPORT
==============================================================================

| ClickUp ID | Name | Shortcut ID | Status |
|---|---|---|---|
| abc123 | Fix login bug | sc-4521 | ✅ Migrated |
| def456 | Update docs | sc-4522 | ✅ Migrated |
| ghi789 | Old task | — | ⚠️ Already exists |

📈 Summary:
  • Total: 3
  • ✅ Migrated: 2
  • ⚠️ Skipped: 1
  • ❌ Failed: 0

Field Mapping Reference

| ClickUp | Shortcut | Notes | |---------|----------|-------| | name | name | Direct copy | | description + attachments | description | Markdown formatted with embedded links | | custom_fields (Sprint Points) | estimate | Parsed as integer for story points | | status | workflow_state_id | Status mapping applied (see Phase 2) | | assignees | owner_ids | Mapped by email/username | | tags | labels | Reused or created as needed | | comments | Story comments | Formatted as **[ClickUp - Author]:** text | | subtasks | Nested stories | Created as subtasks via stories-add-subtask | | url | External link | Added for back-reference |


Advanced Usage

Environment Variables

# Optional: Specify custom workflow (defaults to workspace default)
export SHORTCUT_WORKFLOW_ID=12345

# Optional: Specify team (defaults to workspace)
export SHORTCUT_TEAM_ID=abc-def-ghi

node migrate.js task_id_1 task_id_2

Dry Run (Planned Feature)

node migrate.js task_id --dry-run
# Shows what would be migrated without actually creating stories

Batch Migration from File

Create tasks.txt:

abc123def456
ghi789jkl012
mno345pqr678

Then:

node migrate.js $(cat tasks.txt)

Error Handling

The tool is designed to be resilient:

  • Per-task isolation: If one task fails, migration continues with others
  • Graceful user mapping: If a ClickUp assignee can't be mapped, the story is created without that owner
  • Label creation fallback: If label creation fails, the story is created without that label
  • Comment/subtask failures: Individual comment/subtask failures don't stop story creation

Each result is reported in the final summary table with specific error messages.


Troubleshooting

"Story already migrated"

This means the tool detected an external link pointing to the ClickUp task. The story already exists in Shortcut. If you need to re-migrate, delete the Shortcut story first.

"Failed to map user: [email protected]"

The Shortcut workspace doesn't have a user with this email. Check:

  1. User exists in Shortcut workspace
  2. Email matches exactly in Shortcut
  3. Or add the user to Shortcut and re-run

"Failed to create label"

This usually happens if a label with the same name already exists but wasn't found (case sensitivity). The story is created without that label. You can manually add the label afterward.


Verification Checklist

After migration, verify each story:

  • [ ] Story visible in Shortcut with correct name
  • [ ] Description contains all content from ClickUp (text + embedded images/videos)
  • [ ] Estimate matches Sprint Points (if set)
  • [ ] Status matches ClickUp status (via workflow state)
  • [ ] Assignees/owners correct
  • [ ] Labels present
  • [ ] External link points to original ClickUp task
  • [ ] All comments migrated with author attribution
  • [ ] Subtasks created and linked correctly

Technical Details

Architecture

migrate.js
├─ Phase 0: Initialize Shortcut Environment
│  ├─ mcp__shortcut__workflows-get-default
│  ├─ mcp__shortcut__users-list
│  └─ mcp__shortcut__labels-list
│
├─ Phase 1-3: For each task
│  ├─ Read ClickUp
│  │  ├─ mcp__clickup__clickup_get_task
│  │  └─ mcp__clickup__clickup_get_task_comments
│  │
│  ├─ Transform
│  │  ├─ markdownify description
│  │  ├─ map status
│  │  ├─ parse estimate
│  │  ├─ map users
│  │  └─ map/create labels
│  │
│  └─ Write Shortcut
│     ├─ Check for duplicates (mcp__shortcut__stories-get-by-external-link)
│     ├─ Create story (mcp__shortcut__stories-create)
│     ├─ Add external link (mcp__shortcut__stories-add-external-link)
│     ├─ Migrate comments (mcp__shortcut__stories-create-comment)
│     └─ Migrate subtasks (recursively)
│
└─ Phase 4: Generate Report

MCP Tools Used

ClickUp (Reading):

  • mcp__clickup__clickup_get_task - Get task with subtasks
  • mcp__clickup__clickup_get_task_comments - Get all comments

Shortcut (Writing):

  • mcp__shortcut__workflows-get-default - Get available workflow states
  • mcp__shortcut__users-list - Get user ID mappings
  • mcp__shortcut__labels-list - Get existing labels
  • mcp__shortcut__stories-create - Create main story
  • mcp__shortcut__stories-add-external-link - Add back-reference
  • mcp__shortcut__stories-create-comment - Migrate comments
  • mcp__shortcut__stories-create-subtask or mcp__shortcut__stories-add-subtask - Link subtasks
  • mcp__shortcut__labels-create - Create missing labels
  • mcp__shortcut__stories-get-by-external-link - Check for duplicates

Limitations

  • Image/Video URLs: URLs remain as links; images aren't re-uploaded to Shortcut
  • Custom Fields: Only "Sprint Points" is migrated. Other ClickUp custom fields don't have equivalents
  • Time Tracking: ClickUp time entries aren't migrated (no equivalent in Shortcut)
  • Change History: ClickUp activity history isn't preserved
  • Permissions: Migrated stories inherit workspace defaults; ClickUp-specific permissions aren't replicated
  • Attachments: Embedded as links in description; not re-hosted

Performance

Typical migration times (per task):

  • Single task: ~2-5 seconds
  • Task + 5 comments: ~3-7 seconds
  • Task + 3 subtasks: ~8-15 seconds
  • Batch of 10 tasks: ~30-60 seconds

Times depend on ClickUp/Shortcut API latency.


Support

For issues or feature requests:

  1. Check the Troubleshooting section above
  2. Review error messages in the final report
  3. Verify MCP tools are accessible: /help in Claude Code

License

MIT