Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub enum Command {
#[clap(long)]
no_git: bool,
/// Rust program template to use
#[clap(value_enum, short, long, default_value = "single")]
#[clap(value_enum, short, long, default_value = "multiple")]
template: ProgramTemplate,
/// Test template to use
#[clap(value_enum, long, default_value = "mocha")]
Expand Down Expand Up @@ -230,7 +230,7 @@ pub enum Command {
/// Program name
name: String,
/// Rust program template to use
#[clap(value_enum, short, long, default_value = "single")]
#[clap(value_enum, short, long, default_value = "multiple")]
template: ProgramTemplate,
/// Create new program even if there is already one
#[clap(long, action)]
Expand Down
11 changes: 7 additions & 4 deletions cli/src/rust_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ const ANCHOR_MSRV: &str = "1.89.0";
/// Program initialization template
#[derive(Clone, Debug, Default, Eq, PartialEq, Parser, ValueEnum)]
pub enum ProgramTemplate {
/// Program with a single `lib.rs` file
#[default]
/// Program with a single `lib.rs` file (not recommended for production)
Single,
/// Program with multiple files for instructions, state...
/// Program with multiple files for instructions, state... (recommended)
#[default]
Multiple,
}

Expand All @@ -44,7 +44,10 @@ pub fn create_program(name: &str, template: ProgramTemplate, with_mollusk: bool)
];

let template_files = match template {
ProgramTemplate::Single => create_program_template_single(name, &program_path),
ProgramTemplate::Single => {
println!("Note: Using single-file template. For better code organization and maintainability, consider using --template multiple (default).");
create_program_template_single(name, &program_path)
}
ProgramTemplate::Multiple => create_program_template_multiple(name, &program_path),
};

Expand Down
11 changes: 10 additions & 1 deletion docs/content/docs/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,16 @@ anchor init my-project
```

This command creates a new directory with the project name and initializes a new
Anchor project with a basic Rust program and TypeScript test template.
Anchor project with a modular Rust program structure and TypeScript test
template.

<Callout type="info">

By default, Anchor uses a **modular structure** with separate files for
instructions, state, constants, and errors. This organization improves code
maintainability and is recommended for production code.

</Callout>

Navigate to the project directory:

Expand Down
68 changes: 62 additions & 6 deletions docs/content/docs/quickstart/local.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -65,36 +65,73 @@ Navigate to the new project directory and open it in your code editor.
cd my-project
```

The default Anchor program is located at `/programs/my-project/src/lib.rs`.
By default, Anchor generates a modular program structure to promote better code
organization and maintainability. The program files are organized as follows:

- `/programs/my-project/src/lib.rs` - Main entry point with module declarations
- `/programs/my-project/src/instructions/` - Instruction handlers
- `/programs/my-project/src/state/` - Account structures and state
- `/programs/my-project/src/constants.rs` - Program constants
- `/programs/my-project/src/error.rs` - Custom error definitions

<Accordions>
<Accordion title="Default Program">
<Accordion title="Default Program Structure">

The value in the `declare_id!` macro is the program ID, a unique identifier for
your program.

By default, it is the public key of the keypair generated in
`/target/deploy/my_project-keypair.json`.

**Main entry point** (`lib.rs`):

```rust filename="lib.rs"
pub mod constants;
pub mod error;
pub mod instructions;
pub mod state;

use anchor_lang::prelude::*;

pub use constants::*;
pub use instructions::*;
pub use state::*;

declare_id!("3ynNB373Q3VAzKp7m4x238po36hjAGFXFJB4ybN2iTyg");

#[program]
pub mod my_project {
use super::*;

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
msg!("Greetings from: {:?}", ctx.program_id);
Ok(())
initialize::handler(ctx)
}
}
```

**Instruction handler** (`instructions/initialize.rs`):

```rust filename="instructions/initialize.rs"
use anchor_lang::prelude::*;

#[derive(Accounts)]
pub struct Initialize {}

pub fn handler(ctx: Context<Initialize>) -> Result<()> {
msg!("Greetings from: {:?}", ctx.program_id);
Ok(())
}
```

<Callout type="info">

For simpler projects or quick prototyping, you can use the single-file template
with `anchor init --template single`. However, the modular structure is
recommended for production code as it improves code organization, readability,
and maintainability.

</Callout>

</Accordion>
</Accordions>

Expand Down Expand Up @@ -354,9 +391,17 @@ Below is an overview of default file structure in an Anchor workspace:
<Folder name="[project-name]" defaultOpen={true}>
<Folder name="src" defaultOpen={true}>
<File name="lib.rs" />
<File name="Cargo.toml" />
<File name="Xargo.toml" />
<File name="constants.rs" />
<File name="error.rs" />
<Folder name="instructions" defaultOpen={true}>
<File name="mod.rs" />
<File name="initialize.rs" />
</Folder>
<Folder name="state">
<File name="mod.rs" />
</Folder>
</Folder>
<File name="Cargo.toml" />
</Folder>
</Folder>
<Folder name="target" defaultOpen={true}>
Expand All @@ -383,6 +428,17 @@ Below is an overview of default file structure in an Anchor workspace:
The `/programs` directory contains your project's Anchor programs. A single
workspace can contain multiple programs.

By default, programs are organized with a modular structure:

- `lib.rs` - Main entry point that declares and exports modules
- `instructions/` - Directory containing instruction handler functions
- `state/` - Directory for account structures and state definitions
- `constants.rs` - Program-wide constants
- `error.rs` - Custom error codes

This modular organization makes it easier to navigate and maintain your code,
especially as your program grows in complexity.

### Tests Folder

The `/tests` directory contains test files for your project. A default test file
Expand Down
25 changes: 24 additions & 1 deletion docs/content/docs/references/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ Sets a new authority on the IDL account. Both the `new-authority` and
## Init

```shell
anchor init
anchor init <project-name>
```

Initializes a project workspace with the following structure.
Expand All @@ -231,6 +231,21 @@ Initializes a project workspace with the following structure.
- `tests/`: Directory for JavaScript integration tests.
- `migrations/deploy.js`: Deploy script.

By default, programs are initialized with a **modular structure** (multiple
files) to promote better code organization. This is the recommended approach for
production code.

**Template Options:**

```shell
anchor init --template multiple # Default: Modular structure (recommended)
anchor init --template single # Single lib.rs file (for prototyping)
```

The modular template organizes code into separate files for instructions, state,
constants, and errors, making it easier to navigate and maintain as your program
grows.

## Keys

Program keypair commands.
Expand Down Expand Up @@ -284,6 +299,14 @@ anchor new <program-name>
Creates a new program in the workspace's `programs/` directory initialized with
boilerplate.

By default, uses the **modular structure** template (recommended). You can
specify a different template with the `--template` flag:

```shell
anchor new --template multiple <program-name> # Default: Modular (recommended)
anchor new --template single <program-name> # Single file (for prototyping)
```

## Shell

```shell
Expand Down