I think we should agree on a set of naming conventions for .roc files. What should those conventions be?
Motivation: I'm regularly frustrated by a directory of Roc files - which one is the app? Where is the main? Oh, there are multiple apps in here? I currently feel the need to open every .roc file in a project to understand its structure. A consistent naming approach would make it easier to read and navigate unfamiliar codebases.
Currently, the only constraint on some file names (that I know of) is that a file name must start with a capital letter for it to be imported into another file (the imported file is currently known as an interface, though I expect that a better term exists).
There are three types of roc-related files that app developers must name:
.roc apps.roc interfacesapp "name" header)I propose these naming conventions:
lower_snake_case.roc for appsUpperCamelCase.roc for interfaceslower_snake_case for executable binaries (that don't have a predefined/legacy name or other naming constraints)However, I have questions about every aspect of this:
lowerCamelCase for variables instead of lower_snake_case (which it currently uses for nothing), should app files follow that pattern instead? I think snake_case is the most readable format in general, but consistency is good.app "foo" and platform "bar" headers? Currently they're often redundant with file & directory names.quicksort.app.roc, Random.lib.roc)Multiple suffixes seem like they could create problems because they are pretty rare. Ending the filename of an app file with _app or App seems like a nice way to improve organization without introducing much "noise".
I agree with removing redundant headers when the filename could contain all information.
Personally, I prefer kinda-snake-case.roc for file names. Not sure if that has a specific name, but snake case is definitely my second favorite.
(I believe that's called kebab-case)
I think that we should be careful about messing with extensions because it can make things less portable for no reasons. You put this in a .lib.roc, so you can make it an interface or expose things from it. Go change the name.
Also, I am really not a fan of capitalizing the file name to expose things. I don't want to have to rename files to expose things. We already have an exposes sections for a reason. I can leave it blank if I don't want it my file to get imported. (* I guess someone could still import it, but they couldn't do anything with it)
I want to be pro enforcing a main.roc or lib.roc similar to what rust would do, but that gets complicated with:
Definitely think their should be some sort of solution here, but idk what.
Anyway, that is just my random opinions. I like the idea of adding some structure, but I think it should be minimal if possible.
I think these two are somewhat in tension:
I'm regularly frustrated by a directory of Roc files - which one is the app? Where is the
main? Oh, there are multiple apps in here? I currently feel the need to open every.rocfile in a project to understand its structure.
using roc like a scripting language
I do want Roc to be usable as a scripting language, and it would be weird to create a language-level restriction on how you could name your scripts (even needing to end in .roc isn't currently a requirement)
on the other hand, if there's a convention but it's not enforced, then looking at a directory you can never really be sure which .roc files are and aren't app modules
unless we were to change their file extension, e.g. .rap for roc apps :stuck_out_tongue:
another option could be that interface modules are in a different directory
e.g. the directory structure could be:
examples/
cli/
Hello.roc
Echo.roc
interfaces/
Stuff.roc
so Hello.roc and Echo.roc would be app modules and everything in interfaces/ would be interface modules
then maybe there'd be something like in the app module header like importFrom "interfaces/"
Should we reconsider the
app "foo"andplatform "bar"headers? Currently they're often redundant with file & directory names.
the "foo" in app "foo" controls the name of the generated executable binary. We could automatically generate the same name for the binary as the name of the .roc file but without the .roc extension (and with .exe on Windows). I'd be open to that.
One thing to consider: today I can make a Roc script with no file extension and use #! at the top to make it executable on UNIX systems, so it looks like an ordinary executable to end users. If we had "automatically generate the binary name based on the app filename" then it would by default generate a binary name which overwrote the source file!
Should we reconsider the "importable = capitalized" rule?
file sytem aside, the reason for this rule for module names in general is that Foo.bar vs foo.bar are parsed differently; the former is "the bar value exported by the Foo module" and the latter is "the bar field of the foo record"
they give different error messages depending on whether foo, Foo, and bar exist
I think we should keep that
and if we're keeping that, it would feel weird to me if FooBar.baz came from a module named something other than FooBar.roc - I'm not sure what the advantage would be to allowing (for example) fooBar.roc or foo_bar.roc or something like that
I could see an argument for not repeating the name in the module header, e.g. if the filename is FooBar.roc then maybe we shouldn't say interface FooBar but rather just interface or something like that
(and yeah, there may be a better name than interface but I still don't know of a specific one I like better...a separate discussion!)
I think we could safely try removing the app "foo", interface Bar, and platform "bar" syntaxes for now and see if it causes any DX friction.
If we still value executable renaming, in particular, we could move that feature into a compiler argument. For example: roc build foo.roc --filename=bar_baz.exe. This would allow app consumers to rename the executable (for whatever reason) without needing to edit source. (Although, now that I've said this, I realize that it's trivial to roc build foo.roc && mv foo bar_baz.exe... :/)
platform "bar" is important in the future for specifying how it appears in the package registry
which can't be inferred from filename
e.g. platform "rtfeldman/blah"
today I can make a Roc script with no file extension and use #! at the top to make it executable on UNIX systems, so it looks like an ordinary executable to end users. If we had "automatically generate the binary name based on the app filename" then it would by default generate a binary name which overwrote the source file!
this makes me think app "foo" is worth keeping too
Yeah, headers are more necessary+nuanced than I expected. We should probably defer discussing header improvements to a later topic. (other than how app "foo" interacts with executable file naming)
One thing I've noticed already is that we all have very different preferences and usage patterns! Quite a tricky convention to choose uncontroversially.
We could interpret that as a signal to defer choosing... or as a signal to choose now before fragmentation becomes problematic :confused:
Side note: I love that the .roc file extension isn't even required :laughing: MAXIMUM FLEXIBILITY
[nix-shell:~/_code/_roc/roc]$ cat .DS_Store
app "?" packages { pf: "examples/hello-world/c-platform" } imports [] provides [ main ] to pf
main = "lol"
[nix-shell:~/_code/_roc/roc]$ cargo run .DS_Store
Finished dev [unoptimized + debuginfo] target(s) in 0.26s
Running `target/debug/roc .DS_Store`
🔨 Rebuilding host... Done!
lol
[nix-shell:~/_code/_roc/roc]$
Richard Feldman said:
Should we reconsider the "importable = capitalized" rule?
file sytem aside, the reason for this rule for module names in general is that
Foo.barvsfoo.barare parsed differently; the former is "thebarvalue exported by theFoomodule" and the latter is "thebarfield of thefoorecord"
This makes tons of sense. I definitely don't mind the naming if it is for parsing purposes. It also would definitely be odd if the file name didn't match what it would be imported as.
Though if we end up changing imports and aliases, like how was discussed in other threads, that may make it so that the file name really doesn't matter anymore.
Richard Feldman said:
unless we were to change their file extension, e.g.
.rapfor roc apps :stuck_out_tongue:
A side benefit of this is it would help us with our community name for ourselves: rappers. ha ha /s
Last updated: Jun 16 2026 at 16:19 UTC