Skip to content

@std/path: add a cross-platform resolver that always outputs forward slashes #7151

@theaddonn

Description

@theaddonn

Is your feature request related to a problem? Please describe.

Build tools, bundlers, and any code that produces path strings for programmatic consumption (import specifiers, source maps, cache keys, virtual module IDs) need paths that are portable across operating systems. Currently @std/path offers two options, neither of which is fully correct on Windows:

  • jsr:@std/path: native resolution, but returns backslash paths on Windows (C:\test\foo\bar.ts). Backslash paths break glob matchers, URL construction, and any system that treats / as the path separator.
  • jsr:@std/path/posix: always forward slashes, but treats Windows drive-letter paths (C:\..., C:/...) as relative rather than absolute, because POSIX rules define absolute as "starts with /". Calling posix.resolve("C:/project/src", "./math.ts") silently produces a garbage path by prepending the process CWD.

There is no option that combines native resolution semantics (understands drive letters as absolute) with forward-slash output.

Describe the solution you'd like

A toSlash helper (or a forward submodule mirroring the posix/windows shape) that wraps every @std/path function with native resolution logic but normalizes all output paths to forward slashes:

import { resolve, dirname, join } from "jsr:@std/path/forward";

resolve("C:/project/src", "./math.ts"); // -> "C:/project/src/math.ts"  correct on Windows
resolve("/home/user/src", "./math.ts"); // -> "/home/user/src/math.ts"  correct on Linux/Mac

Alternatively, a single toSlash(path: string): string export on the main module would let callers opt in without a new submodule.

Describe alternatives you've considered

  • jsr:@std/path/posix + drive-letter stripping: strip C:, run posix.resolve, re-attach C:. Works but is fragile- it relies on the drive letter always being one character, breaks for UNC paths, and is easy to get wrong.
  • jsr:@std/path (native) + manual str.replace(/\\/g, "/") on every output: what most projects end up doing. It works but it's boilerplate that every consumer has to repeat and remember to apply consistently to every path function's return value.

Both workarounds are commonly reinvented across the ecosystem. A stdlib-provided solution would eliminate a class of subtle cross-platform bugs for any Deno project that handles file paths programmatically.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions