Building programs on Solana with pure Rust can have a lot of learning curve; you’ll have to import this, write that way and so on.
More importantly, such programs are more susceptible to security breaches, especially when written by a Junior SVM dev and the code was not audited by cracked SVM security researchers.
For this and many other reasons, we have Anchor. I prefer to call Anchor the lightweight Rust framework for the SVM.
One of the major reasons you might want to get interested in Anchor is that a good number of top Solana protocols were built with it. Examples include Drift V2, MarginFi, and Marinade Finance.
So far, these protocols have been largely unbroken. In addition, the source code are very easy to read.
That is another thing to know about Anchor; you can read it even if you are not so cracked, all you need to do is calm down and maybe check the docs here and there.
That said, the main goal of this tutorial is to help you write your first “Hello World” with Anchor. I’ll break it down to the lowest bit.
Trust me, once you can confidently write this “Hello World” and understood why you wrote each word, you’re set to have a strong foundation building with Anchor.
Let’s dive in!
Step-by-step Guide to Writing First “Hello World” with Anchor on Solana
In this subheading, we’ll be getting straight to the business.
Prerequisite
Before you can run any program on the Solana Virtual Machine, you need to have these things on your machine:
Install Solana
The best way to install Solana is to simply run this code:
curl --proto '=https' --tlsv1.2 -sSfL https://solana-install.solana.workers.dev | bash
By the way, ensure you use Ubuntu as your terminal for this to be successful.
You should see this on your terminal once it’s done:
Installed Versions:
Rust: rustc 1.85.0 (4d91de4e4 2025-02-17)
Solana CLI: solana-cli 2.1.15 (src:53545685; feat:3271415109, client:Agave)
Anchor CLI: anchor-cli 0.31.1
Node.js: v23.9.0
Yarn: 1.22.1
Installation complete. Please restart your terminal to apply all changes.
If you run into any error, you can check my video, which is more elaborate on this:
Solana Playground
If you’re coming from the EVM background, you know we all started off with Remix for writing, compiling, and deployment of smart contracts.
Something similar is on Solana, and that is the Solana Playground.
You don’t need to download anything. You can access it via your browser and it will work fine.
Another alternative to this is building locally with VS Code or any code editor of your choice. While there is nothing wrong with that, you most likely shouldn’t use that for a start.
More like the way you didn’t start writing Solidity with Foundry; at least, most of us didn’t.
In short, it’s better to kick-off with the Playground.
Step 1: Using the Prelude
Open the Solana Playground, create a file called hello.rs
, and paste this:
use anchor_lang::prelude::*;
You might want to ask, why did we write that? Or, what does it mean? There is quite a long explanation to that.
Like we mentioned earlier, Anchor is a lightweight version of Rust on Solana. Meaning many things have been compressed or made easier, so Anchor can have a smoother sail (smile if you got the pun).
We use the prelude
of Anchor as a way to import all the simplified components, macros, types, and error handlings of Anchor into our program.
Let me give you an example:
Imagine all the every important thing you’ll need on a trip is in your bag; laptop, power station, duvet and so on.
You have arrived at your destination.
Instead of picking each item one by one, is it not smarter to carry the entire bag?
That’s the same thing we did with prelude
of Anchor.
It imported all the macros we need such as #[program], #[derive(Accounts)
and so on. In the same way, all the types and error handling are also brought into the scope of our program.
The longer route of what we wrote above is:
use anchor_lang:: Context;
use anchor_lang:: prelude:: Account;
use anchor_lang:: Accounts;
use anchor_lang:: Result;
// and so on
You will keep writing this individual imports based on what you want to do in your protocol. But use anchor_lang::prelude::*;
has simplified and embedded everything.
Meanwhile, using the prelude is not the end. You have to call the types in your program later on, and we will get to that.
Step 2: Declaration of ID
declare_id!("");
This is one of the macros in Anchor, and there is an orthodox approach to it; it has to be at the root of any program you write.
Think of it as both the deployment address. In practice, you can generate this address before deployment with keypair-json
command, and then use it as your ID.
But for the scope of this tutorial, you only need to write declare_id!("");
and the Playground will automatically generate one for you.
This is the source with which the SVM as well as users will interact with your program. Hence, your OpSec has to be tight so it won’t be breached.
Step 3: Write the Program Macro
#[program]
Without inputting this macro, the compiler will not understand where the actual contract is located within your program.
In short, you need to write #[program]
for the compiler to know anything within this macro is part of the core logic of your protocol.
As you’ll later know, there are other macros in a program, and each one of them has what it does.
In the instant case, #[program]
is a blanket of logic under which you write how you expect your application to work.
Step 4: Create the Hello World Module
mod hello_world {
use super::*;
We created a module for proper organization of our code and named it hello_world
. Then we use super::*;
.
Remember how we brought in the essential components of Anchor into the program in step 1 through use anchor_lang::prelude::*;;
.
Now, those components are only available globally and not locally.
What that mean is that the macros we imported through it won’t be automatically recognizable in this module we created.
If you were to write Context, Result
or any other component, the compiler will throw an error.
For this reason, we imported those components locally via use super::*
.
By super
, we mean what is above or outside of the module; above it. This will make the SVM catch that we are trying to use the simplified Anchor components we brought into the scope of this program from the beginning at this stage.
Hope you got that.
Step 4: Hello World Function
pub fn hello(ctx: Context<Hello>) -> Result<()> {
msg!("Hello World, this is John the Dev");
Ok(())
}
}
This is a public function named hello
, with a contextual parameter called Hello
. This is a null returning function; meaning we are not expecting it to return a number or anything else.
Hence, there is nothing indicated within the bracket after Result.
We input a message there that says, Hello World, this is John the Dev
.
Then we input Ok(())
, which indicates that we intentionally do not want the function to return anything.
Step 5: Account Validation
#[derive(Accounts)]
pub struct Hello{}
For performance and security reasons, you don’t want all accounts to interact with your program, and this is where this macro is important.
Or even if you want them to, you might want to bounce off accounts that do not have the minimum amount of SOL to interact with your program.
Whatever commercial or security considerations you might have.
In the instant case, we want don’t want anyone to interact with our Hello World. Hence, we put an empty Hello
struct.
Full Code:
If you’ve done everything above correctly, this should be your full code by now:
use anchor_lang::prelude::*;
declare_id!("Af1mHQijv9vDdQtzukBNzTC9RgezfuQyWVoZzn3HMvxz");
#[program]
mod hello_world {
use super::*;
pub fn hello(ctx: Context<Hello>) -> Result<()> {
msg!("Hello World, this is John the Dev");
Ok(())
}
}
#[derive(Accounts)]
pub struct Hello{}
Step 6: Compilation
Now that you are done with your program. Click on the Build
button, and your program will be compiled.
Or, you can rather input anchor build
into the terminal. You should see something like this:
Build successful
How to Test Anchor Programs with Solana Playground
This is a simple aspect. Click on the test tube icon, then click on Test.
Testing 'hello'...
Loading Solana CLI...
Success.
RPC URL: https://api.devnet.solana.com
Default Signer: Playground Wallet
Commitment: confirmed
$
Transaction executed in slot 393363660:
Block Time: 2025-07-10T13:28:16+01:00
Version: Legacy
Recent Blockhash: EyX2KcqJAoemP25AzDN8PaTsP8F015nm76XttLqftz6A
Signature 0: mmBbogbTagy3AoR1TzPnF4TY7CZzUg5MfJ7va4UWo2zrv8ME7Jy6aBCPZYMYYpTT06TDX1urGck6g7snTKgiR3W Account 0: srw- HWMSXjDBaUCqCygDXs5UHBX2zUxwnVMeguArfpgVK18 (fee payer)
Account 1: -r-x Af1mHQijv9vDdQtzukBNzTC9RgezfuQyWVoZzn3HMvxz Instruction 0
Program: Af1mHQijv9vDdQtzukBNzTC9RgezfuQyWVoZzn3HMvxz (1)
Data: [149, 118, 59, 220, 196, 127, 161, 179]
Status: OK
Fee: 0.000005
Account 0 balance: 6.8147046 -> 6.8146996
Account 1 balance: 0.00139896
Log Messages:
Program Af1mHQijv9vDdQtzukBNZTC9RgezfuQyWVoZzn3HMvxz invoke [1]
Program Log: Instruction: Hello
Program Log: Hello World
Program Af1mHQijv9vDdQtzukBNzTC9RgezfuQyWVoZzn3HMvxz consumed 443 of 200000 compute units Program Af1mHQijv9vDdQtzukBNzTC9RgezfuQyWVoZzn3HMvxz success
Confirmed $
Conclusion
Congratulations! You just got your feet into Anchor. Now, that you’ve written your first Hello World
in Anchor, don’t stay there.
Take a step further to learn how to create an expense tracker with Anchor. Building this next project will make you understand Anchor better and be more creative with it.
Since you’ve read to this stage, you can as well check out the video format on YouTube; comment and subscribe!
Top comments (0)