Solidity Libraries: Write Once, Use Everywhere


Solidity, the smart contract language of Ethereum,enables one to build decentralized applications that run on-chain. But as the codebase grows, it can quickly get messy by repeating the same logic across contracts, bloating bytecode, and making life harder than it needs to be.
That’s where libraries come in.
What Is a Library in Solidity?
A library in Solidity is like a toolbox: it’s a reusable collection of functions that can be shared by other contracts. You write the logic once in a library, and then call it from other contracts, thereby saving gas, reducing repetition, and keeping your code DRY (Don’t Repeat Yourself).
A practical example:
Library = A collection of read-only or stateless helpers
Contract = A full-blown smart contract that stores data and controls app logic
Solidity libraries are not meant to hold contract state (i.e., no storage variables) and cannot send Ether.
Why Use Libraries?
Reusability: One library, many contracts.
Gas Optimisation: Reduces bytecode duplication.
Clean Architecture: Keeps contracts smaller and focused.
Security: Avoid repeating bugs across multiple contracts.
Types of Libraries
There are two ways to use libraries in Solidity:
1. Embedded (Internal) Libraries
Functions are copied into the contract at compile time.
Cheaper to deploy since you don’t deploy the library separately.
Only allows
internal
functions.
library Math {
function add(uint a, uint b) internal pure returns (uint) {
return a + b;
}
}
Usage:
contract Calculator {
using Math for uint;
function sum(uint a, uint b) public pure returns (uint) {
return a.add(b);
}
}
2. Deployed (External) Libraries
The library is deployed as a separate contract.
Can only use
external
orpublic
functions.Saves bytecode on each contract that uses it.
They must be linked to the library manually during deployment.
library MathExternal {
function multiply(uint a, uint b) external pure returns (uint) {
return a * b;
}
}
Usage in contracts:
import "./MathExternal.sol";
contract UseExternal {
function product(uint a, uint b) public pure returns (uint) {
return MathExternal.multiply(a, b);
}
}
Limitations of Libraries
No state variables allowed.
No Ether transfers.
Cannot inherit from other contracts or be inherited.
Cannot have fallback or receive functions.
They’re designed to be stateless, lean, and utility-focused.
Behind the Scenes: How Libraries Work
When using X for Y
Solidity internally changes how you call methods:
using Math for uint;
a.add(b); // becomes Math.add(a, b);
Best Practices When Using Libraries
Grouping similar functions together (e.g., math, validation).
Using
pure
orview
functions because they don’t modify state.Marking functions as
internal
for embedded libraries.Not using them to store state or transfer ETH.
Giving library files clear names like
MathLib.sol
orSafeTransferLib.sol
.
Feature | Internal Library | External Library |
Deployment | Embedded in contract | Deployed separately |
Function types | internal only | public , external |
Gas Cost | Higher per use | Lower (shared) |
Use case | Simple helpers | Reusable large modules |
Subscribe to my newsletter
Read articles from akindewa directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
