Skip to main content

Command Palette

Search for a command to run...

.fsx vs .fs

Updated
3 min read
.fsx vs .fs

Understanding F# Files: .fsx vs .fs (with a Practical stat.fsx Example)

When learning F#, one of the first confusions beginners face is the difference between .fsx files (F# scripts) and .fs files (source files part of a project). Understanding this distinction is essential for writing efficient scripts, experimenting, or developing full-fledged applications.


1️⃣ .fsx — F# Script Files

.fsx files are interactive scripts, designed for quick prototyping, automation, or teaching. They are executed directly by F# Interactive (FSI) and do not require compilation.

Key Features:

  • Execution: Interpreted top-to-bottom via dotnet fsi script.fsx

  • EntryPoint: Optional

  • References: Can include packages or DLLs inline using #r "..."

  • Order Matters: Code runs sequentially as written

Use Case: Quick experiments, file processing scripts, teaching examples.


Example: stat.fsx — Show File/Directory Metadata

This script demonstrates how to get size, last modified time, and permissions for files and directories:

open System
open System.IO

/// Show metadata for a file or directory
let showStat path =
    if File.Exists path then
        let f = FileInfo path
        printfn "File: %s" f.FullName

    elif Directory.Exists path then
        let d = DirectoryInfo path

        printfn "Last modified: %s" (d.LastWriteTime.ToString())
    else
        printfn "stat: cannot stat '%s': No such file or directory" path

/// Get command-line argument from FSI
let args =
    if fsi.CommandLineArgs.Length > 1 then fsi.CommandLineArgs.[1..] else [||]

match args with
| [| path |] -> showStat path
| _ -> printfn "Usage: dotnet fsi stat.fsx <file-or-directory>"

Run the script:

dotnet fsi stat.fsx /path/to/file

This is perfect for learning file I/O in F# and demonstrates a practical use of .fsx scripts.


2️⃣ .fs — F# Source Files

.fs files are part of a formal F# project. They are compiled using the project file (.fsproj) and produce a DLL or EXE.

Key Features:

  • Execution: Compiled → run via dotnet run or referenced as a library

  • EntryPoint: [<EntryPoint>] required for console apps

  • References: Managed via .fsproj or NuGet

  • Use Case: Multi-file applications, production software, libraries

Example: A console application, library, or large F# service.


3️⃣ .fsx vs .fs — Quick Comparison

Feature.fsx.fs
Executiondotnet fsi script.fsxdotnet builddotnet run
Build required❌ No✅ Yes
EntryPointOptionalRequired for console apps
Multi-fileLess commonStandard
ReferencesInline (#r)Project-managed (.fsproj)

4️⃣ When to Use Which

  • Use .fsx for learning, scripting, automation, or experiments.

  • Use .fs when building production applications, libraries, or multi-file projects.

The stat.fsx example is a perfect demonstration of .fsx usage: a self-contained script that interacts with the filesystem, useful for both learning F# I/O and practical scripting.


💡 Pro Tip: Start small with .fsx scripts to prototype functionality quickly. Once your logic stabilizes and your code grows, migrate it into a .fsproj project with .fs files for a more maintainable and production-ready structure.