Skip to content

Conversation

@sigmachirality
Copy link
Member

@sigmachirality sigmachirality commented Jan 20, 2026

Due to bugs arising from the iteraction of packages like inquirer and ora and the node-compat functionality of Deno such as denoland/deno#30747, we are migrating away from Deno back to Node for now.

We remain excited by the development of alternate JS runtimes such as Deno and Bun, but are focused on delivering a good UX for our customers as a top priority, of which bugs detract from.

Due to: yao-pkg/pkg-fetch#134, we must polyfill Intl.Segmenter using @formatjs.

@semanticdiff-com
Copy link

semanticdiff-com bot commented Jan 20, 2026

Review changes with  SemanticDiff

Changed Files
File Status
  src/lib/sell.ts  100% smaller
  src/schema.ts  98% smaller
  src/lib/buy/index.tsx  95% smaller
  src/helpers/format-date.ts  95% smaller
  src/lib/orders/OrderDisplay.tsx  93% smaller
  src/lib/scale/ProcurementDisplay.tsx  92% smaller
  src/helpers/units.ts  91% smaller
  src/index.ts  89% smaller
  src/lib/scale/ConfirmationMessage.tsx  89% smaller
  src/lib/scale/utils.ts  88% smaller
  src/lib/nodes/list.tsx  87% smaller
  src/lib/extend/index.tsx  87% smaller
  src/lib/nodes/create.ts  86% smaller
  src/lib/orders/__tests__/OrderDisplay.test.ts  86% smaller
  src/lib/scale/update.tsx  84% smaller
  src/lib/tokens.ts  80% smaller
  src/lib/nodes/release.ts  80% smaller
  src/lib/contracts/index.tsx  79% smaller
  src/lib/scale/create.tsx  78% smaller
  src/lib/vm/logs.ts  78% smaller
  src/lib/vm/index.ts  76% smaller
  src/lib/nodes/delete.ts  76% smaller
  src/lib/nodes/redeploy.ts  74% smaller
  src/lib/scale/list.tsx  73% smaller
  src/lib/nodes/image/show.tsx  72% smaller
  src/helpers/instance-types-meta.ts  71% smaller
  src/lib/nodes/image/upload.ts  71% smaller
  src/lib/nodes/set.ts  67% smaller
  src/lib/vm/list.ts  67% smaller
  src/lib/nodes/logs.ts  63% smaller
  src/lib/vm/ssh.ts  63% smaller
  src/lib/dev.ts  61% smaller
  src/lib/nodes/utils.ts  61% smaller
  src/lib/contracts/ContractDisplay.tsx  58% smaller
  src/lib/balance.ts  56% smaller
  src/lib/nodes/ssh.ts  53% smaller
  src/lib/nodes/image/index.ts  51% smaller
  src/lib/ConfirmInput.tsx  51% smaller
  src/helpers/config.ts  50% smaller
  src/lib/zones.tsx  48% smaller
  src/lib/posthog.ts  47% smaller
  .github/workflows/ci.yml  47% smaller
  src/lib/sell/index.tsx  44% smaller
  src/scripts/release.ts  43% smaller
  src/lib/upgrade.ts  42% smaller
  .vscode/settings.json  42% smaller
  src/lib/nodes/image/list.tsx  40% smaller
  src/lib/Quote.tsx  39% smaller
  src/lib/vm/replace.ts  39% smaller
  src/lib/nodes/extend.ts  36% smaller
  src/lib/login.ts  34% smaller
  package.json  28% smaller
  src/helpers/feature-flags.ts  28% smaller
  src/helpers/test/duration.test.ts  26% smaller
  src/lib/orders/index.tsx  25% smaller
  src/lib/nodes/get.tsx  22% smaller
  src/helpers/test/units.test.ts  22% smaller
  src/lib/Row.tsx  20% smaller
  .github/workflows/release.yml  16% smaller
  src/helpers/errors.ts  6% smaller
  src/lib/scale/index.tsx  1% smaller
  src/checkVersion.ts  1% smaller
  .tool-versions Unsupported file format
  .vscode/extensions.json  0% smaller
  README.md Unsupported file format
  biome.json  0% smaller
  bun.lock Unsupported file format
  deno.json  0% smaller
  deno.lock Unsupported file format
  install.sh Unsupported file format
  src/helpers/duration.ts  0% smaller
  src/helpers/fetchers.ts  0% smaller
  src/lib/app-banner.ts  0% smaller
  src/lib/index.ts  0% smaller
  src/lib/me.ts  0% smaller
  src/lib/nodes/index.ts  0% smaller
  src/lib/vm/script.ts  0% smaller
  tsconfig.json  0% smaller
  tsup.config.ts  0% smaller
  vitest.config.ts  0% smaller

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 20, 2026

Greptile Summary

Migrates the CLI from Deno runtime to Node.js to resolve compatibility issues with interactive terminal libraries (inquirer, ora) that were causing bugs in Deno's node-compat layer.

Key Changes:

  • Build pipeline: Replaced deno compile with tsup (bundler) + @yao-pkg/pkg (native compiler)
  • Runtime APIs: Migrated all Deno-specific APIs (Deno.readTextFile, Deno.Command, etc.) to Node.js equivalents (fs/promises, child_process)
  • Dependencies: Downgraded ink from v5 to v4 (via ink-cjs alias), added @formatjs/intl-segmenter polyfill to prevent segfaults in pkg builds
  • Tooling: Switched from Deno's built-in formatter/linter to Biome, and from Deno test to Vitest
  • Package manager: Uses Bun for dependency management and task running (development only)

Issues Found:

  • Missing stub file src/stubs/react-devtools-core.ts referenced in tsup.config.ts:19 will cause build failures

Confidence Score: 3/5

  • This PR is moderately safe but requires fixing the missing stub file before merging
  • The migration is comprehensive and well-executed, with proper API migrations and polyfills. However, the missing react-devtools-core stub file will cause immediate build failures. The score reflects this critical issue that must be resolved before deployment.
  • tsup.config.ts requires immediate attention to fix the missing stub file reference

Important Files Changed

Filename Overview
tsup.config.ts New bundler configuration using tsup/esbuild to replace Deno compile. References missing stub file ./src/stubs/react-devtools-core.ts in alias configuration.
package.json Migrated dependencies from Deno to Node ecosystem. Uses ink-cjs alias for ink v4 compatibility. Added Intl.Segmenter polyfill and build tooling.
src/index.ts Wrapped main execution in async function, added Intl.Segmenter polyfill import, migrated from fetch to apiClient. Uses Number.isNaN instead of isNaN.
src/scripts/release.ts Migrated from Deno APIs to Node.js fs/child_process. Now uses tsup bundling + pkg compilation instead of deno compile. Added --no-commit dry-run flag.
src/lib/upgrade.ts Migrated from Deno.Command to Node child_process.spawn with proper stream handling. Changed from TextEncoder/Decoder to string operations. Still has exit code null check issue flagged earlier.
src/lib/nodes/image/upload.ts Migrated file I/O from Deno to Node.js fs/promises. Changed from Deno.open to fs.open, updated chunk reading logic, and migrated color imports from JSR std to chalk.
.github/workflows/release.yml Updated CI from Deno to Bun. Replaced deno fmt/lint/check/test with biome, tsc, and vitest.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as sf CLI (Node)
    participant Build as Build Pipeline
    participant Runtime as Node Runtime
    
    Note over User,Runtime: Development Flow
    User->>CLI: bun run dev/prod [command]
    CLI->>Runtime: Load Intl.Segmenter polyfill
    CLI->>Runtime: Initialize async main()
    Runtime->>CLI: Execute command with Node APIs
    
    Note over User,Runtime: Build & Release Flow
    User->>Build: Trigger release workflow
    Build->>Build: Run biome lint + tsc check
    Build->>Build: Run vitest tests
    Build->>Build: Bump version in package.json
    Build->>Build: tsup: Bundle src → dist/index.cjs
    Build->>Build: pkg: Compile to native binaries
    Note right of Build: Targets: node22-linux-x64/arm64,<br/>node22-macos-x64/arm64
    Build->>Build: Create zip archives
    Build->>Build: Create GitHub release
    
    Note over User,Runtime: Installation Flow  
    User->>CLI: curl install.sh | bash
    CLI->>CLI: Detect OS/architecture
    CLI->>CLI: Download sf-node22-{platform}-{arch}.zip
    CLI->>CLI: Extract to ~/.local/bin/sf
    User->>Runtime: sf [command]
    Runtime->>User: Execute with bundled dependencies
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Comments (3)

  1. src/lib/orders/index.tsx, line 332 (link)

    syntax: Typo in header key: 'Content-ype' should be 'Content-Type'

  2. src/lib/scale/update.tsx, line 248 (link)

    logic: missing dependencies in useEffect - should include updateProcurements, nodesRequired, and other values used in the effect

  3. src/lib/zones.tsx, line 153-159 (link)

    logic: Color functions cyan, green, red, and gray are not imported from chalk or defined elsewhere - these will cause runtime errors

77 files reviewed, 12 comments

Edit Code Review Agent Settings | Greptile

@sigmachirality sigmachirality changed the title refactor: move from Deno to Node runtime refactor: move from deno to node runtime Jan 20, 2026
@sigmachirality sigmachirality changed the title refactor: move from deno to node runtime refactor!: move from deno to node runtime Jan 20, 2026
@sigmachirality sigmachirality self-assigned this Jan 20, 2026
sigmachirality and others added 18 commits January 20, 2026 16:46
- Add tsconfig.json with bundler moduleResolution for tsx runtime
- Restore biome.json from git history for linting/formatting
- Add vitest.config.ts for test runner configuration

Part of Deno to Node.js migration (Phase 1: Setup)
- Add "type": "module" for ESM support
- Add pkg configuration for binary compilation
- Update scripts: dev, prod, lint, check, test
- Add devDependencies: typescript, tsx, vitest, @biomejs/biome, @yao-pkg/pkg
- Add chalk dependency (replaces jsr:@std/fmt/colors)
- Add type declarations: @types/cli-progress, @types/async-retry
- Add bun.lock for bun package manager

Part of Deno to Node.js migration (Phase 1: Setup)
Files updated:
- src/helpers/config.ts: Deno.readTextFile -> fs.readFile, etc.
- src/helpers/feature-flags.ts: Deno.mkdir -> fs.mkdir, etc.
- src/lib/upgrade.ts: Deno.Command -> child_process.spawn
- src/lib/clusters/kubeconfig.ts: Deno.errors -> Node.js error codes
- src/lib/clusters/keys.tsx: Deno.chmod -> fs.chmod
- src/lib/nodes/image/upload.ts: Deno.open -> fs.open, Deno.exit -> process.exit

Replaced APIs:
- Deno.readTextFile() -> fs.promises.readFile()
- Deno.writeTextFile() -> fs.promises.writeFile()
- Deno.mkdir() -> fs.promises.mkdir()
- Deno.Command -> child_process.spawn()
- Deno.errors.NotFound -> err.code === 'ENOENT'

Part of Deno to Node.js migration (Phase 3)
Migrated 26 files from Deno's JSR color imports to chalk:
- import { cyan, gray, yellow } from "jsr:@std/fmt/colors"
  -> import chalk from "chalk"
- cyan("text") -> chalk.cyan("text")
- brightRed("text") -> chalk.redBright("text")

Part of Deno to Node.js migration (Phase 4)
Updated imports from Deno-specific npm: namespace to standard:
- import boxen from "npm:boxen@8.0.1" -> import boxen from "boxen"
- import yn from "npm:yn" -> import yn from "yn"
- import * as nacl from "npm:tweetnacl" -> import nacl from "tweetnacl"

Part of Deno to Node.js migration (Phase 4)
Updated 5 test files:
- src/helpers/test/units.test.ts
- src/helpers/test/duration.test.ts
- src/lib/orders/__tests__/OrderDisplay.test.ts
- src/lib/clusters/kubeconfig.test.ts
- src/lib/clusters/utils.test.ts

Changes:
- Deno.test("name", fn) -> test("name", fn)
- assertEquals(a, b) -> expect(a).toEqual(b)
- import from "jsr:@std/assert" -> import from "vitest"

Part of Deno to Node.js migration (Phase 5)
ci.yml:
- Replace denoland/setup-deno with actions/setup-node
- Replace deno fmt/lint/check/test with npm run lint/check/test

release.yml:
- Replace deno setup with Node.js 20
- Replace deno run with npx tsx for release script
- Use npm ci for dependency installation

Part of Deno to Node.js migration (Phase 6)
- Delete deno.json (Deno runtime configuration)
- Delete deno.lock (Deno dependency lock file)
- Update .tool-versions to remove deno, keep nodejs 20.19.0

Part of Deno to Node.js migration (Phase 7: Cleanup)
- Replace deno compile with npx pkg for binary compilation
- Map pkg targets to original output names for backward compatibility:
  - node20-linux-x64 -> sf-x86_64-unknown-linux-gnu
  - node20-linux-arm64 -> sf-aarch64-unknown-linux-gnu
  - node20-macos-x64 -> sf-x86_64-apple-darwin
  - node20-macos-arm64 -> sf-aarch64-apple-darwin
- Replace Deno.Command with child_process.spawnSync
- Replace Deno.readTextFile/writeTextFile with fs.readFileSync/writeFileSync

Part of Deno to Node.js migration
- Remove unused @ts-expect-error directives after migration
- Add explicit type assertions for response.json() calls
- Fix 'unknown' type errors by adding proper type casts

Files: me.ts, orders/index.tsx, tokens.ts, posthog.ts, vm/replace.ts
- Remove @ts-expect-error directive in index.ts
- Update import organization (biome)
- Minor error handling improvements
Auto-fixed by biome check --write:
- Organize imports alphabetically
- Fix quote style consistency
- Remove unused imports
- Standardize formatting
Auto-generated schema file reformatted by biome for consistency.
No functional changes.
Comprehensive migration plan documenting:
- CI workflow updates
- Release process changes (deno compile -> pkg)
- Auto-upgrade compatibility considerations
- Deno-specific packages replaced (jsr:, npm:, Deno.* APIs)
- Configuration changes (tsconfig, biome, vitest)
- Migration phases and execution order
Fixes tsx warning about unsettled top-level await by wrapping
the entire script in an async main() function.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use biomejs/setup-biome@v2 for proper biome installation
and run biome ci for optimized CI output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update release script and install.sh to use pkg target names
(node20-linux-x64, etc.) instead of mapping to Deno-style names.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace Deno setup instructions with Node.js
- Update development commands (npm run dev/prod)
- Update CI quality checks (biome, tsc, vitest)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
sigmachirality and others added 27 commits January 20, 2026 16:55
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use oven-sh/setup-bun@v2 and bun commands instead of
actions/setup-node@v4 with npm. Bun is the package manager.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaced Deno formatter with Biome for various file types in settings.json and updated extension recommendations accordingly.
- Updated number parsing to use Number.isNaN for clarity.
- Streamlined string formatting in various log messages and commands for consistency.
- Removed unnecessary type stripping and improved readability in several files.
@sigmachirality
Copy link
Member Author

@greptileai review again

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

76 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

esbuildOptions(options) {
options.bundle = true;
options.alias = {
"react-devtools-core": "./src/stubs/react-devtools-core.ts",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: missing stub file

The stub file ./src/stubs/react-devtools-core.ts referenced in this alias doesn't exist in the repository. This will cause the build to fail when esbuild tries to resolve this alias.

Suggested change
"react-devtools-core": "./src/stubs/react-devtools-core.ts",
// "react-devtools-core": "./src/stubs/react-devtools-core.ts",

Either create the stub file or remove this alias if it's not needed.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tsup.config.ts
Line: 19:19

Comment:
**syntax:** missing stub file

The stub file `./src/stubs/react-devtools-core.ts` referenced in this alias doesn't exist in the repository. This will cause the build to fail when esbuild tries to resolve this alias.

```suggestion
      // "react-devtools-core": "./src/stubs/react-devtools-core.ts",
```

Either create the stub file or remove this alias if it's not needed.

How can I resolve this? If you propose a fix, please make it concise.

@sigmachirality sigmachirality changed the title refactor!: move from deno to node runtime refactor!: [ENG-2327] move from deno to node runtime Jan 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants