# SE-0513: API to get the path to the current executable

**URL:** <https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800>\
**Category:** Proposal Reviews\
**Tags:** stdlib\
**Created:** [February 18, 2026, 2:44pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800 "2026-02-18T14:44:13Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [February 19, 2026, 2:44pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/21 "2026-02-19T14:44:49Z")

</div>

> [@grynspan](#):
>
> If this is the direction we end up going, we should consider also adding something like `public var CommandLine.argumentCStrings: Array<Array<CChar | CWideChar>> { get }` for the same reasons.

FWIW, `CommandLine` already has [`unsafeArgv`](https://developer.apple.com/documentation/swift/commandline/unsafeargv) whose type is `UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>`, so that use case feels like it's already reasonably covered. Offering the fully unsafe version, the fully safe `[String]` version, _and_ a middle-ground array of arrays of `CChar` version would be quite a bit of API surface.

So the question is whether that middle use case is worth optimizing for. Maybe? It's obviously true that many elements of `argv` are going to be file paths, so if you need to support paths that aren't valid UTF-8, you would _have_ to use `unsafeArgv` instead of `arguments`. I can almost guarantee that most Swift code in production that deals with command lines isn't handling this correctly today.

This is one of those times where I wish we had a better "bag of bytes" or "platform string" type besides `[UInt8]` or `[CChar]` because the type system could express exactly what is intended here and it could provide good APIs to convert them to more specific representations. Obviously outside the scope of this proposal, of course.

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [February 19, 2026, 3:00pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/22 "2026-02-19T15:00:47Z")

</div>

> [@allevato](#):
>
> FWIW, `CommandLine` already has [`unsafeArgv`](https://developer.apple.com/documentation/swift/commandline/unsafeargv) whose type is `UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>`, so that use case feels like it's already reasonably covered. Offering the fully unsafe version, the fully safe `[String]` version, _and_ a middle-ground array of arrays of `CChar` version would be quite a bit of API surface.

I'm aware of `unsafeArgv`, but note just _how_ unsafe it is: it's global mutable state! We don't like that! So yes, I'd be advocating for (beyond this proposal) revisiting `unsafeArgv` and providing something that lets us deprecate and replace `unsafeArgv` outright with the same basic semantics as `executablePathCString`.

> [@allevato](#):
>
> This is one of those times where I wish we had a better "bag of bytes" or "platform string" type besides `[UInt8]` or [CChar]` because the type system could express exactly what is intended here and it could provide good APIs to convert them to more specific representations. Obviously outside the scope of this proposal, of course.

Long ago, we had [`CString`](https://github.com/swiftlang/swift/commit/c34b4f6a9e358b1083d664eb4f330ed101b40525), but then ~~the Fire Nation attacked~~ Swift as a whole went in a different direction and said "C strings are pointers and Swift strings are Unicode".

---

<div class="post-metadata">

**Author:** ![kebo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kebo/32/6918_2.png) [@kebo](https://forums.swift.org/u/kebo)\
**Post date:** [February 19, 2026, 4:31pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/23 "2026-02-19T16:31:14Z")

</div>

> This property is explicitly unavailable in Embedded Swift and WASI: if in the future we can reliably get a value for this property in Embedded Swift or on WASI, we ought to be able to lift these constraints.

It makes sense to make it unavailable for Embedded Swift, but I don't think so for WASI. I think just returning `argv[0]` is better than making it unavailable.

A WASI executable is typically executed within a sandbox environment, so I believe `argv[0]` is sufficient for `executablePath` on WASI. If it's unavailable on WASI, we can't easily use `executablePath` when creating a cross-platform command-line tool that supports WASI. Thus, that also becomes a problem for other platforms.

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [February 19, 2026, 4:43pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/24 "2026-02-19T16:43:48Z")

</div>

> [@kebo](#):
>
> A WASI executable is typically executed within a sandbox environment, so I believe `argv[0]` is sufficient for `executablePath` on WASI. If it's unavailable on WASI, we can't easily use `executablePath` when creating a cross-platform command-line tool that supports WASI. Thus, that also becomes a problem for other platforms.

Okay: let's say we make it available on WASI. What are you doing with it where `argv[0]` (an arbitrary string of unknown nature) is an appropriate substitute? What is the code that needs `executablePath` but is entirely happy to take an arbitrary string on WASI?

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [February 19, 2026, 4:47pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/25 "2026-02-19T16:47:21Z")

</div>

It won't be an arbitrary string on WASI, it'll be a name of the module or the component containing the module. IMO it should return `CommandLine.arguments.first` on WASI and `nil` for non-WASI Embedded Swift.

In its current form the proposal making it unavailable on those platforms gets a -1 from me.

Packages that adopted `CommandLine.arguments.first` work on all those platforms, but if they adopt API from the proposal as currently stated they'll become less portable, which IMO is worse than the status quo.

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [February 19, 2026, 4:50pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/26 "2026-02-19T16:50:34Z")

</div>

`argv[0]` is arbitrary per the C standard. If WASI provides stronger guarantees, are they documented anywhere?

Is [` __progname` or `__ progname_full`](https://github.com/search?q=repo%3AWebAssembly%2Fwasi-libc+progname&type=code) (from Musl) available in wasi-libc? Perhaps we could use one or the other?

**Edit:** Emscripten [sets it](https://github.com/emscripten-core/emscripten/pull/16064). I don't see any references to either in WasmKit or wasmtime.

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [February 19, 2026, 4:55pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/27 "2026-02-19T16:55:33Z")

</div>

> [@grynspan](#):
>
> Is [` __progname` or `__ progname_full`](https://github.com/search?q=repo%3AWebAssembly%2Fwasi-libc+progname&type=code) (from Musl) available in wasi-libc? Perhaps we could use one or the other?

You shouldn't rely on presence of WASI-libc when building Swift for arbitrary WASI version. I could see a package adopting WASI 0.2/0.3+ syscalls directly without WASI-libc in the future, we would call [WASI CLI syscalls](https://github.com/WebAssembly/WASI/blob/main/proposals/cli/command.md) directly in `CommandLine.arguments`. In this scenario `CommandLine.arguments.first` would be the right implementation for both embedded and non-embedded packages supporting WASI. For the record, I don't have an opinion preference for how other platforms implement it.

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [February 19, 2026, 5:09pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/28 "2026-02-19T17:09:25Z")

</div>

> [@Max\_Desiatov](#):
>
> You shouldn't rely on presence of WASI-libc when building Swift for arbitrary WASI version.

Well, it was just a thought. 🙂

> [@Max\_Desiatov](#):
>
> In this scenario `CommandLine.arguments.first` would be the right implementation for both embedded and non-embedded packages supporting WASI.

I'd refer you to the [**motivation**](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0513-commandline-executablepath.md#motivation) section of this proposal; if `argv[0]` (or `CommandLine.arguments.first`—same thing) were appropriate for this purpose in the general case, this API wouldn't be necessary in the first place.

If Wasm or WASI gives stricter guarantees about the value of `argv[0]` and we can refer back to documentation on the subject, I'd be happy to revise the proposal to use `argv[0]` there, but I'm not aware of any such guarantees. Can you point me to any relevant documentation?

---

<div class="post-metadata">

**Author:** ![icharleshu](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/icharleshu/32/20905_2.png) [@icharleshu](https://forums.swift.org/u/icharleshu)\
**Post date:** [February 19, 2026, 7:04pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/29 "2026-02-19T19:04:29Z")

</div>

> [@allevato](#):
>
> [SE-0513: API to get the path to the current executable](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0513-commandline-executablepath.md)

Biiiiig +1 from me as well. Currently, we have `SwiftFoundation` (re)implementing this exact logic in `Platform.getFullExecutablePath`; `Bundle` also heavily depends on this functionality to work.

---

<div class="post-metadata">

**Author:** ![awwright](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/awwright/32/40477_2.png) [@awwright](https://forums.swift.org/u/awwright)\
**Post date:** [February 20, 2026, 6:50pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/31 "2026-02-20T18:50:45Z")

</div>

How does this proposal plan to _implement_ the feature? Presumably, it has to receive this information from the operating system somehow, so as an alternative, can't you call out to these APIs directly like Boost does?

CommandLine is just a common interface, specified in C, for calling a function in an executable file, passing in a list of strings and receiving back a number. It doesn't make any other assumptions, not even that there's a filesystem.

This should be placed together with a cross-platform package that implements the other POSIX-style assumptions, like environment variables and a filesystem; not CommandLine.

* * *

I think as another alternative, the arguments, environment variables, and other context should be passed to the `init` or `main` function, depending on what's available from the environment, but without assuming that these exist on all platforms (e.g. WASM).

Currently, the "CommandLine" interface is an empty enum that contains static properties whose value changes from process to process. You can't actually create an instance of `CommandLine` and fill it with values.

Instead, I should be able to define a `main` function that can receive values such as the command line arguments, environment variables, and current executable file path, whatever is available from the calling environment. Then all other functions/methods are identical between environments, and cannot see environment differences except for what is read and handled by the main/init function.

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [February 20, 2026, 6:58pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/32 "2026-02-20T18:58:22Z")

</div>

> [@awwright](#):
>
> How does this proposal plan to _implement_ the feature?

The proposal has a link to the implementation, which you can look at.

Proposal reviews should generally be less concerned about "how" something is implemented than "that" it can be implemented; however, the line can perhaps be blurred in situations like this where an API exposes platform details that are inherently implementation-specific. If you have specific concerns about how implementation choices might impact the design of the API, or what user-facing behavior would be surfaced by those choices, of course those are fair game.

---

<div class="post-metadata">

**Author:** ![awwright](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/awwright/32/40477_2.png) [@awwright](https://forums.swift.org/u/awwright)\
**Post date:** [February 20, 2026, 7:28pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/33 "2026-02-20T19:28:09Z")

</div>

> [@allevato](#):
>
> The proposal has a link to the implementation, which you can look at.

Ah, I did pass over this link entirely. Yeah, I wouldn't expect this proposal to make system calls; this is only weakly hinted at even though it's presented as a feature of the _programming language_, in order to suspect this, I would at least first have to know that this isn't a feature of the actual interface of `main` that the parent calls.

If CommandLine is going to be the implementation of the common, environment-independent standard that works across platforms and the programming languages they're calling into, then resolving the executable path should be in a separate operating system API or system call package (though a cross platform one).

---

<div class="post-metadata">

**Author:** ![awwright](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/awwright/32/40477_2.png) [@awwright](https://forums.swift.org/u/awwright)\
**Post date:** [March 4, 2026, 7:37pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/34 "2026-03-04T19:37:23Z")

</div>

Are there intended use cases for this feature besides the two examples from the first thread? I see the initial pitch includes two examples, but neither are interoperable:

`posix_spawn(executablePath, ...)` Usually you want to use `fork` instead, which will spawn the child even if the executable is moved or unlinked.

`let resourcesDirectory = "\(executablePath)-resources"` This assumes that the resources will always be in the same location as the executable, but most -nix distributions do not accommodate this. You're still reliant on environment-specific patterns to distribute and locate resources, for example, [Bundle](https://developer.apple.com/documentation/foundation/bundle) is exactly the pattern you are supposed to use if you need to bundle resources with the executable, _because_ a raw executable is insufficient. (i.e. The proposal's observation that Bundle is 'fairly "high up" in the stack' isn't a bug, it's the solution.)

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [March 4, 2026, 7:58pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/35 "2026-03-04T19:58:45Z")

</div>

> [@awwright](#):
>
> `posix_spawn(executablePath, ...)` Usually you want to use `fork` instead, which will spawn the child even if the executable is moved or unlinked.

`fork()` creates a new process with a clone of the parent's state including its address space, file descriptors, etc. But it doesn't copy any of the other threads of a multithreaded program; the call to `fork()` acts much like a call to a signal handler, and in fact it is unsafe to do _anything_ in the child process that isn't explicitly [async-signal-safe](https://man7.org/linux/man-pages/man7/signal-safety.7.html).

You _cannot_ safely call `fork()` from Swift\[1\]. See for example [this](https://forums.swift.org/t/how-to-prevent-crash-due-to-swift-runtime-initializing-os-log-on-macos/81842) past discussion about it. Oh, and [this](https://www.microsoft.com/en-us/research/wp-content/uploads/2019/04/fork-hotos19.pdf) short paper from Microsoft Research.

On Darwin in particular, `fork()` is effectively deprecated and is only ever really seen in code that's a straight port from some flavour of UNIX. If a forked child process touches Core Foundation before calling `execve()` (or related), the process terminates. In the general case, a program written in Swift and running on Darwin is _probably_ linking against Core Foundation directly or indirectly.

> [@awwright](#):
>
> (i.e. The proposal's observation that Bundle is 'fairly "high up" in the stack' isn't a bug, it's the solution.)

While I wouldn't advise the average Swift developer to go reimplementing `Bundle`, `Bundle` itself needs to look up the executable path of the current process in order to implement resource discovery. 🙂

* * *

1. You _can_ call `fork()` from C/C++ in a program that also includes Swift, but only if you call `execve()` (or related) _immediately_ afterward. This is effectively how `posix_spawn()` is implemented on some platforms, of course.

---

<div class="post-metadata">

**Author:** ![compnerd](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/compnerd/32/2165_2.png) [@compnerd](https://forums.swift.org/u/compnerd)\
**Post date:** [March 4, 2026, 8:08pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/36 "2026-03-04T20:08:41Z")

</div>

> [@awwright](#):
>
> Usually you want to use `fork` instead, which will spawn the child even if the executable is moved or unlinked.

Could you please elaborate on why you believe that? `fork` is definitely far riskier than `posix_spawn` and possibly can even leak resources unless you are extremely careful. The general recommendation tends to be to prfer `posix_spawn`.

While here ...

> - What is your evaluation of the proposal?

I think that this is a worthy addition to the current API surface.

> - Is the problem being addressed significant enough to warrant a change to Swift?

I feel like this problem comes up every so often, so, yes, its something that does warrant a change to Swift.

> - Does this proposal fit well with the feel and direction of Swift?

Yes

> - If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I think that it is decently comparable to the Boost solution. I think that it might possibly be better as: ` public static var executablePath: String { get throws }`, but the current shape is reasonable as well. A throwing variant might allow for more error information to propagate.

> - How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

A quick glance through the proposal and a peek into the implementation.

---

<div class="post-metadata">

**Author:** ![fclout](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/fclout/32/36155_2.png) [@fclout](https://forums.swift.org/u/fclout)\
**Post date:** [March 4, 2026, 10:15pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/37 "2026-03-04T22:15:07Z")

</div>

How does this fit with the pitch of adding a FilePath type to the standard library?

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [March 4, 2026, 10:33pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/38 "2026-03-04T22:33:44Z")

</div>

That's an open question right now. If we end up adding such a type, it makes sense for this property to have that type. However that's still just a pitch, and one for which there is a fair bit of active discussion, so I don't think we can guess what the outcome will be.

We may end up delaying this proposal until that question is resolved. That's for the LSG to decide.

---

<div class="post-metadata">

**Author:** ![awwright](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/awwright/32/40477_2.png) [@awwright](https://forums.swift.org/u/awwright)\
**Post date:** [March 5, 2026, 12:34am UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/39 "2026-03-05T00:34:08Z")

</div>

> [@grynspan](#):
>
> You _cannot_ safely call `fork()` from Swift . See for example [this](https://forums.swift.org/t/how-to-prevent-crash-due-to-swift-runtime-initializing-os-log-on-macos/81842) past discussion about it. Oh, and [this](https://www.microsoft.com/en-us/research/wp-content/uploads/2019/04/fork-hotos19.pdf) short paper from Microsoft Research.

So? `fork()` is the given POSIX API for doing this in an interoperable manner. If Swift has problems with forking the process, let's file a new proposal.

> [@grynspan](#):
>
> While I wouldn't advise the average Swift developer to go reimplementing `Bundle`, `Bundle` itself needs to look up the executable path of the current process in order to implement resource discovery. 🙂

Who's proposing developers re-implement Bundle?

I'm not saying "looking up the executable path" is always bad, I'm saying building a bundle then calling Bundle.resourcePath is the correct framework to do this in a repeatable manner.

> [@compnerd](#):
>
> Could you please elaborate on why you believe that? `fork` is definitely far riskier than `posix_spawn` and possibly can even leak resources unless you are extremely careful. The general recommendation tends to be to prfer `posix_spawn`.

This isn't a meaningful distinction to my point... posix\_spawn is just a special case of a fork then exec. The point is you don't need a file on the filesystem, you don't even need a filesystem to spawn children with the correct API.

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [March 5, 2026, 12:46am UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/40 "2026-03-05T00:46:05Z")

</div>

This discussion of `fork` vs. `posix_spawn` and how they are supported (or not) by Swift would be better done in a separate thread; it's fairly tangential to the API being proposed.

If you want to ask for more concrete motivating use cases that don't involve spawning new processes, that's fine, but that goal isn't served by doing a more technical deep dive of `fork` here.

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [March 9, 2026, 3:17pm UTC](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800/41 "2026-03-09T15:17:38Z")

</div>

This proposal has been [returned for revision](https://forums.swift.org/t/returned-for-revision-se-0513-api-to-get-the-path-to-the-current-executable/85220). Thanks to everyone who participated in the review!

[Previous page](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800.md?page=1)

[Next page](https://forums.swift.org/t/se-0513-api-to-get-the-path-to-the-current-executable/84800.md?page=3)
