The Flutter
Micro-framework
For Modern Apps
Nylo gives every project the same solid foundation — routing, state, networking, forms and auth — so you start at feature one instead of file one.
dart pub global activate nylo_installer
Everything you need to build
Six pillars, one convention. Each ships with Metro generators, sensible defaults and an escape hatch — it's still plain Flutter underneath.
Routing
Declarative routes with guards, typed parameters, transitions and deep linking.
State management
Reactive state with controllers, lifecycle hooks and painless persistence.
Networking
API service classes with automatic model decoding and request interceptors.
Forms
Declare fields once — validation, casting and data binding come with them.
Authentication
Session handling, token storage and route guards without a bespoke setup.
Metro CLI
Generate pages, models, controllers, forms and themes from one command.
Create anything from the terminal
Metro scaffolds pages, models, controllers, widgets and more — wired into your router and folder structure, not dumped in a corner.
class ApiService extends NyApiService {
@override
String get baseUrl => "https://api.example.com/v1";
Future<List<Post>> posts() async {
return await network(
request: (request) => request.get("/posts"),
);
}
}
// Usage in your page
final posts = await api<ApiService>((request) => request.posts());
Effortless API integration
Write clean, maintainable API services with automatic JSON parsing, error handling and request interceptors — no Dio boilerplate in your pages.
Learn more about NetworkingSee it in the code you'd actually write
appRouter() => nyRoutes((router) {
router.add(HomePage.path).initialRoute();
router.add(DiscoverPage.path);
router.add(LoginPage.path,
transitionType: TransitionType.bottomToTop());
router.add(ProfilePage.path,
routeGuard: [
AuthGuard()
]
);
});
Build complex routes, interfaces and UI pages for your Flutter application.
Learn moreAuthenticate a user
String userToken = "eyJhbG123...";
await Auth.authenticate(data: {"token": userToken});
Now, when your user opens the app they will be authenticated.
final userData = Auth.data();
// {"token": "eyJhbG123..."}
bool isAuthenticated = await Auth.isAuthenticated();
// true
If you've set an authenticatedRoute in your router, then it will present this page when the user opens the app again.
appRouter() => nyRoutes((router) {
...
router.add(LandingPage.path).initialRoute();
router.add(DashboardPage.path).authenticatedRoute();
// overrides the initial route when a user is authenticated
Logout the user
await Auth.logout();
Authenticate users in your Flutter application.
Learn moreCreate a Form
metro make:form RegisterForm
Modify your form
class RegisterForm extends NyFormWidget {
RegisterForm({super.key, super.submitButton, super.onSubmit, super.onFailure});
// Add your fields here
@override
fields() => [
Field.capitalizeWords("name",
label: "Name",
validator: FormValidator.notEmpty(),
),
Field.email("email_address",
label: "Email",
validator: FormValidator.email()
),
Field.password("password",
label: "Password",
validator: FormValidator.password(),
),
];
static NyFormActions get actions => const NyFormActions("RegisterForm");
}
Use your form in a widget
@override
Widget build(BuildContext context) {
return Scaffold(
body: RegisterForm(
submitButton: Button.primary(text: "Submit"),
onSubmit: (data) {
printInfo(data);
},
),
);
}
Manage, validate and submit data all in one place with Nylo Forms.
Learn moreCreate a state managed widget
metro make:stateful_widget CartIcon
class _CartIconState extends NyState<CartIcon> {
...
@override
Map<String, Function> get stateActions => {
"clear_cart": () {
_items = 0;
},
...
};
@override
Widget view(BuildContext context) {
return Container(child: Text("Items in cart: ${_items}"));
}
}
Use CartIcon.action("clear_cart")
Button.primary(text: "Add to cart",
onPressed: () {
CartIcon.action("clear_cart");
}
)
Powerful state management for widgets in your Flutter application.
Learn moreCreate your event
metro make:event Logout
class LogoutEvent implements NyEvent {
@override
final listeners = {
DefaultListener: DefaultListener(),
};
}
class DefaultListener extends NyListener {
@override
handle(dynamic event) async {
// logout user
await Auth.logout();
// redirect to home page
routeTo(HomePage.path,
navigationType: NavigationType.pushAndForgetAll
);
}
}
Dispatch the event
MaterialButton(child: Text("Logout"),
onPressed: () {
event<LogoutEvent>();
},
)
Dispatch events and listen for them in your application.
Learn moreSchedule a task to run once
Nylo.scheduleOnce("onboarding_info", () {
print("Perform code here to run once");
});
Schedule a task to run once after a specific date
Nylo.scheduleOnceAfterDate("app_review_rating", () {
print("Perform code to run once after DateTime(2025, 04, 10)");
}, date: DateTime(2025, 04, 10));
Schedule a task to run once daily
Nylo.scheduleOnceDaily("free_daily_coins", () {
print("Perform code to run once daily");
});
Schedule tasks to run once or daily in your Flutter application.
Learn moreCreate an API Service
metro make:api_service User
class UserApiService extends NyApiService {
@override
String get baseUrl => getEnv("API_BASE_URL");
Future<User?> fetchUser(int id) async {
return await get<User>(
"/users/$id",
queryParameters: {"include": "profile"},
);
}
Future<User?> createUser(Map<String, dynamic> data) async {
return await post<User>("/users", data: data);
}
}
Call the API from your page
User? user = await api<UserApiService>(
(request) => request.fetchUser(1),
);
Elegant API services with automatic JSON parsing, caching, and interceptors.
Learn moreSave data securely
// Save values to secure storage
await NyStorage.save("coins", 100);
await NyStorage.save("username", "Anthony");
await NyStorage.save("isPremium", true);
// Save with TTL (auto-expires)
await NyStorage.save("session", "abc123",
expiry: Duration(hours: 1),
);
Read with type casting
// Automatic type casting
String? username = await NyStorage.read("username");
int? coins = await NyStorage.read<int>("coins");
bool? isPremium = await NyStorage.read<bool>("isPremium");
// Delete a value
await NyStorage.delete("coins");
Secure local storage with type casting, TTL expiry, and collections.
Learn moreAdd your language files
{
"welcome": "Welcome",
"greeting": "Hello {{name}}",
"navigation": {
"home": "Home",
"profile": "Profile"
}
}
Translate text in your widgets
// Simple translation
Text("welcome".tr()) // "Welcome"
// With arguments
Text("greeting".tr(arguments: {"name": "Anthony"}))
// "Hello Anthony"
// Nested keys
Text("navigation.home".tr()) // "Home"
Multi-language support with JSON files, arguments, and RTL.
Learn moreCreate a Navigation Hub
metro make:navigation_hub base
class _BaseNavigationHubState extends NavigationHub<BaseNavigationHub> {
NavigationHubLayout? layout = NavigationHubLayout.bottomNav();
@override
bool get maintainState => true;
_BaseNavigationHubState() : super(() async {
return {
0: NavigationTab(
title: "Home",
page: HomeTab(),
icon: Icon(Icons.home),
),
1: NavigationTab(
title: "Settings",
page: SettingsTab(),
icon: Icon(Icons.settings),
),
};
});
}
Switch layouts easily
// Bottom navigation
NavigationHubLayout.bottomNav()
// Top navigation
NavigationHubLayout.topNav()
// Journey / wizard flow
NavigationHubLayout.journey()
Build bottom nav, top nav, or journey flows with state maintenance.
Learn moreBuilt in the open, used in production
“I'm new to Dart and new to your framework — which I love.”
“Nylo is the best framework for Flutter — it makes developing easy.”
@higakijin
“By far the best framework out there. Amazing quality and features.”
@2kulfi
“It makes the work easier and less time consuming. Great work.”
darkreader01
“Just discovered this framework and I'm very impressed. Thank you.”
@lepresk
“Really love the concept of this framework.”
@Chrisvidal
“I wanted to thank you guys for the great job you are doing.”
@youssefKadaouiAbbassi
“Just to say that I am in love with @nylo_dev's website!”
@esfoliante_txt
“This is incredible. Very well done!”
FireflyDaniel
Your next Flutter app starts with one command
Free, MIT licensed, and it's still just Flutter underneath.
dart pub global activate nylo_installer