ЁЯОЙ Nylo v7 рдЖ рдЧрдпрд╛ рд╣реИ! рдирдпрд╛ рдХреНрдпрд╛ рд╣реИ рджреЗрдЦреЗрдВ тЖТ

Nylo Website logo

Flutter
рдорд╛рдЗрдХреНрд░реЛ-рдлреНрд░реЗрдорд╡рд░реНрдХ
рдЖрдзреБрдирд┐рдХ рдРрдкреНрд╕ рдХреЗ рд▓рд┐рдП

Flutter рдРрдкреНрд╕ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдордЬрдмреВрдд рдЖрдзрд╛рд░ред рд░рд╛рдЙрдЯрд┐рдВрдЧ, рд╕реНрдЯреЗрдЯ рдореИрдиреЗрдЬрдореЗрдВрдЯ, рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ, рдФрд░ рдмрд╣реБрдд рдХреБрдЫ тАФ рд╕рдм рдПрдХ рд╕реБрдВрджрд░ рдкреИрдХреЗрдЬ рдореЗрдВред

рд╢реБрд░реВ рдХрд░реЗрдВ
рдЦреЛрдЬреЗрдВ
рд╕реБрд╡рд┐рдзрд╛рдПрдВ

рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЬреЛ рдХреБрдЫ рднреА рдЪрд╛рд╣рд┐рдП

Nylo рдЖрдкрдХреЛ рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕ рдХреЗ рд╕рд╛рде рдкреНрд░реЛрдбрдХреНрд╢рди-рд░реЗрдбреА Flutter рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдЯреВрд▓ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред

рд░рд╛рдЙрдЯрд┐рдВрдЧ

рд░реВрдЯ рдЧрд╛рд░реНрдбреНрд╕, рдкреИрд░рд╛рдореАрдЯрд░реНрд╕ рдФрд░ рдбреАрдк рд▓рд┐рдВрдХрд┐рдВрдЧ рд╕рдкреЛрд░реНрдЯ рдХреЗ рд╕рд╛рде рд╕рд░рд▓, рдШреЛрд╖рдгрд╛рддреНрдордХ рд░рд╛рдЙрдЯрд┐рдВрдЧред

рд╕реНрдЯреЗрдЯ рдореИрдиреЗрдЬрдореЗрдВрдЯ

рдХрдВрдЯреНрд░реЛрд▓рд░реНрд╕ рдФрд░ рдЖрд╕рд╛рди рд╕реНрдЯреЗрдЯ рдкрд░реНрд╕рд┐рд╕реНрдЯреЗрдВрд╕ рдХреЗ рд╕рд╛рде рдмрд┐рд▓реНрдЯ-рдЗрди рд░рд┐рдПрдХреНрдЯрд┐рд╡ рд╕реНрдЯреЗрдЯ рдореИрдиреЗрдЬрдореЗрдВрдЯред

рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ

рдСрдЯреЛрдореИрдЯрд┐рдХ рдореЙрдбрд▓ рд╕реАрд░рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдФрд░ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░реНрд╕ рдХреЗ рд╕рд╛рде рд╕реБрдВрджрд░ API рд╕рд░реНрд╡рд┐рд╕ рдХреНрд▓рд╛рд╕реЗрд╕ред

рдлреЙрд░реНрдореНрд╕

рд╡реИрд▓рд┐рдбреЗрд╢рди, рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдФрд░ рдСрдЯреЛрдореИрдЯрд┐рдХ рдбреЗрдЯрд╛ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдлреЙрд░реНрдо рд╣реИрдВрдбрд▓рд┐рдВрдЧред

рдкреНрд░рдорд╛рдгреАрдХрд░рдг

рд░реВрдЯ рдЧрд╛рд░реНрдбреНрд╕, рдЯреЛрдХрди рд╕реНрдЯреЛрд░реЗрдЬ рдФрд░ рд╕реЗрд╢рди рдореИрдиреЗрдЬрдореЗрдВрдЯ рдХреЗ рд╕рд╛рде рд╕реБрд░рдХреНрд╖рд┐рдд рдкреНрд░рдорд╛рдгреАрдХрд░рдгред

Metro CLI

рд╢рдХреНрддрд┐рд╢рд╛рд▓реА CLI рдХрдорд╛рдВрдбреНрд╕ рдХреЗ рд╕рд╛рде рдкреЗрдЬ, рдореЙрдбрд▓, рдХрдВрдЯреНрд░реЛрд▓рд░ рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рдЬрдирд░реЗрдЯ рдХрд░реЗрдВред

Metro CLI

рдЯрд░реНрдорд┐рдирд▓ рд╕реЗ рдХреБрдЫ рднреА рдмрдирд╛рдПрдВ

Metro Nylo рдХрд╛ CLI рдЯреВрд▓ рд╣реИ рдЬреЛ рдПрдХ рдХрдорд╛рдВрдб рд╕реЗ рдкреЗрдЬ, рдореЙрдбрд▓, рдХрдВрдЯреНрд░реЛрд▓рд░, рд╡рд┐рдЬреЗрдЯ рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рд╕реНрдХреИрдлреЛрд▓реНрдб рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред

Metro рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдЬрд╛рдиреЗрдВ
metro make:page HomePage
# Creates a new page called HomePage

metro make:api_service User
# Creates a new API Service called UserApiService

metro make:model User
# Creates a new model called User

metro make:stateful_widget FavouriteWidget
# Creates a new stateful widget called FavouriteWidget
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());
рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ

рдЖрд╕рд╛рди API рдЗрдВрдЯреАрдЧреНрд░реЗрд╢рди

рдСрдЯреЛрдореИрдЯрд┐рдХ JSON рдкрд╛рд░реНрд╕рд┐рдВрдЧ, рдПрд░рд░ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдФрд░ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░реНрд╕ рдХреЗ рд╕рд╛рде рд╕рд╛рдл, рдореЗрдВрдЯреЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп API рд╕рд░реНрд╡рд┐рд╕реЗрдЬ рд▓рд┐рдЦреЗрдВред

рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдЬрд╛рдиреЗрдВ
рдЦреЛрдЬреЗрдВ

рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЯреВрд▓реНрд╕

рдЕрдкрдирд╛ рдЕрдЧрд▓рд╛ Flutter рдРрдк рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЬреЛ рдХреБрдЫ рднреА рдЪрд╛рд╣рд┐рдП

routes/router.dart
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()
        ]
    );
});

рдЕрдкрдиреЗ Flutter рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдЬрдЯрд┐рд▓ рд░реВрдЯ, рдЗрдВрдЯрд░рдлреЗрд╕ рдФрд░ UI рдкреЗрдЬ рдмрдирд╛рдПрдВред

рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВ
рдЪрд░рдг 1

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреНрд░рдорд╛рдгрд┐рдд рдХрд░реЗрдВ

String userToken = "eyJhbG123...";

await Auth.authenticate(data: {"token": userToken});
рдЪрд░рдг 2

рдЕрдм, рдЬрдм рдЖрдкрдХрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдРрдк рдЦреЛрд▓реЗрдЧрд╛ рддреЛ рд╡реЗ рдкреНрд░рдорд╛рдгрд┐рдд рд╣реЛрдВрдЧреЗред

final userData = Auth.data();
// {"token": "eyJhbG123..."}

bool isAuthenticated = await Auth.isAuthenticated();
// true
рдЪрд░рдг 3

рдпрджрд┐ рдЖрдкрдиреЗ рдЕрдкрдиреЗ рд░рд╛рдЙрдЯрд░ рдореЗрдВ authenticatedRoute рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдлрд┐рд░ рд╕реЗ рдРрдк рдЦреЛрд▓реЗрдЧрд╛ рддреЛ рдпрд╣ рдкреЗрдЬ рдкреНрд░рд╕реНрддреБрдд рд╣реЛрдЧрд╛ред

routes/router.dart
appRouter() => nyRoutes((router) {
    ...
    router.add(LandingPage.path).initialRoute();

    router.add(DashboardPage.path).authenticatedRoute();
    // overrides the initial route when a user is authenticated

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд▓реЙрдЧрдЖрдЙрдЯ рдХрд░реЗрдВ

await Auth.logout();

рдЕрдкрдиреЗ Flutter рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдкреНрд░рдорд╛рдгрд┐рдд рдХрд░реЗрдВред

рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВ
рдЪрд░рдг 1

рдлреЙрд░реНрдо рдмрдирд╛рдПрдВ

terminal
metro make:form RegisterForm
рдЪрд░рдг 2

рдЕрдкрдирд╛ рдлреЙрд░реНрдо рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░реЗрдВ

app/forms/register_form.dart
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");
}
рдЪрд░рдг 3

рд╡рд┐рдЬреЗрдЯ рдореЗрдВ рдЕрдкрдирд╛ рдлреЙрд░реНрдо рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

register_page.dart
@override
Widget build(BuildContext context) {
  return Scaffold(
    body: RegisterForm(
      submitButton: Button.primary(text: "Submit"),
      onSubmit: (data) {
        printInfo(data);
      },
    ),
  );
}

Nylo Forms рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рдбреЗрдЯрд╛ рдкреНрд░рдмрдВрдзрд┐рдд, рдорд╛рдиреНрдп рдФрд░ рд╕рдмрдорд┐рдЯ рдХрд░реЗрдВред

рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВ
рдЪрд░рдг 1

рд╕реНрдЯреЗрдЯ рдореИрдиреЗрдЬреНрдб рд╡рд┐рдЬреЗрдЯ рдмрдирд╛рдПрдВ

terminal
metro make:stateful_widget CartIcon
resources/cart_icon_widget.dart
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}"));
  }
}
рдЪрд░рдг 2

Use CartIcon.action("clear_cart")

another widget
Button.primary(text: "Add to cart",
    onPressed: () {
      CartIcon.action("clear_cart");
    }
)

рдЖрдкрдХреЗ Flutter рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╡рд┐рдЬреЗрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕реНрдЯреЗрдЯ рдореИрдиреЗрдЬрдореЗрдВрдЯред

рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВ
рдЪрд░рдг 1

рдЕрдкрдирд╛ рдЗрд╡реЗрдВрдЯ рдмрдирд╛рдПрдВ

terminal
metro make:event Logout
app/events/logout_event.dart
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
        );
    }
}
рдЪрд░рдг 2

рдЗрд╡реЗрдВрдЯ рдбрд┐рд╕реНрдкреИрдЪ рдХрд░реЗрдВ

MaterialButton(child: Text("Logout"),
    onPressed: () {
        event<LogoutEvent>();
    },
)

рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдЗрд╡реЗрдВрдЯ рдбрд┐рд╕реНрдкреИрдЪ рдХрд░реЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕реБрдиреЗрдВред

рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВ

рдПрдХ рдмрд╛рд░ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рд╕реНрдХ рд╢реЗрдбреНрдпреВрд▓ рдХрд░реЗрдВ

Nylo.scheduleOnce("onboarding_info", () {
    print("Perform code here to run once");
});

рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рддрд╛рд░реАрдЦ рдХреЗ рдмрд╛рдж рдПрдХ рдмрд╛рд░ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рд╕реНрдХ рд╢реЗрдбреНрдпреВрд▓ рдХрд░реЗрдВ

Nylo.scheduleOnceAfterDate("app_review_rating", () {
    print("Perform code to run once after DateTime(2025, 04, 10)");
}, date: DateTime(2025, 04, 10));

рджреИрдирд┐рдХ рдПрдХ рдмрд╛рд░ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рд╕реНрдХ рд╢реЗрдбреНрдпреВрд▓ рдХрд░реЗрдВ

Nylo.scheduleOnceDaily("free_daily_coins", () {
    print("Perform code to run once daily");
});

рдЕрдкрдиреЗ Flutter рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдПрдХ рдмрд╛рд░ рдпрд╛ рджреИрдирд┐рдХ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рд╕реНрдХ рд╢реЗрдбреНрдпреВрд▓ рдХрд░реЗрдВред

рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВ
рдЪрд░рдг 1

API рд╕рд░реНрд╡рд┐рд╕ рдмрдирд╛рдПрдВ

terminal
metro make:api_service User
app/networking/user_api_service.dart
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);
    }
}
рдЪрд░рдг 2

рдЕрдкрдиреЗ рдкреЗрдЬ рд╕реЗ API рдХреЙрд▓ рдХрд░реЗрдВ

User? user = await api<UserApiService>(
    (request) => request.fetchUser(1),
);

рдСрдЯреЛрдореИрдЯрд┐рдХ JSON рдкрд╛рд░реНрд╕рд┐рдВрдЧ, рдХреИрд╢рд┐рдВрдЧ рдФрд░ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░реНрд╕ рдХреЗ рд╕рд╛рде рд╕реБрдВрджрд░ API рд╕рд░реНрд╡рд┐рд╕реЗрдЬред

рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВ
рдЪрд░рдг 1

рдбреЗрдЯрд╛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рд╕реЗрд╡ рдХрд░реЗрдВ

saving_data.dart
// 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),
);
рдЪрд░рдг 2

рдЯрд╛рдЗрдк рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдкрдврд╝реЗрдВ

// 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");

рдЯрд╛рдЗрдк рдХрд╛рд╕реНрдЯрд┐рдВрдЧ, TTL рдПрдХреНрд╕рдкрд╛рдпрд░реА рдФрд░ рдХрд▓реЗрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╕реБрд░рдХреНрд╖рд┐рдд рд▓реЛрдХрд▓ рд╕реНрдЯреЛрд░реЗрдЬред

рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВ
рдЪрд░рдг 1

рдЕрдкрдиреА рднрд╛рд╖рд╛ рдлрд╛рдЗрд▓реЗрдВ рдЬреЛрдбрд╝реЗрдВ

lang/en.json
{
    "welcome": "Welcome",
    "greeting": "Hello {{name}}",
    "navigation": {
        "home": "Home",
        "profile": "Profile"
    }
}
рдЪрд░рдг 2

рдЕрдкрдиреЗ рд╡рд┐рдЬреЗрдЯреНрд╕ рдореЗрдВ рдЯреЗрдХреНрд╕реНрдЯ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдВ

// Simple translation
Text("welcome".tr())  // "Welcome"

// With arguments
Text("greeting".tr(arguments: {"name": "Anthony"}))
// "Hello Anthony"

// Nested keys
Text("navigation.home".tr())  // "Home"

JSON рдлрд╛рдЗрд▓реЛрдВ, рдЖрд░реНрдЧреБрдореЗрдВрдЯреНрд╕ рдФрд░ RTL рдХреЗ рд╕рд╛рде рдмрд╣реБ-рднрд╛рд╖рд╛ рд╕рдорд░реНрдердиред

рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВ
рдЪрд░рдг 1

рдиреЗрд╡рд┐рдЧреЗрд╢рди рд╣рдм рдмрдирд╛рдПрдВ

terminal
metro make:navigation_hub base
resources/pages/base_navigation_hub.dart
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),
            ),
        };
    });
}
рдЪрд░рдг 2

рд▓реЗрдЖрдЙрдЯ рдЖрд╕рд╛рдиреА рд╕реЗ рдмрджрд▓реЗрдВ

// Bottom navigation
NavigationHubLayout.bottomNav()

// Top navigation
NavigationHubLayout.topNav()

// Journey / wizard flow
NavigationHubLayout.journey()

рд╕реНрдЯреЗрдЯ рдореЗрдВрдЯреЗрдиреЗрдВрд╕ рдХреЗ рд╕рд╛рде рдмреЙрдЯрдо рдиреЗрд╡, рдЯреЙрдк рдиреЗрд╡ рдпрд╛ рдЬрд░реНрдиреА рдлреНрд▓реЛ рдмрдирд╛рдПрдВред

рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВ

рд╕рдореБрджрд╛рдп рджреНрд╡рд╛рд░рд╛ рдкрд╕рдВрдж рдХрд┐рдпрд╛ рдЧрдпрд╛

рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреНрдпрд╛ рдХрд╣ рд░рд╣реЗ рд╣реИрдВ Nylo Website

рдЪрд░реНрдЪрд╛ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВ

I'm new to Dart and new to your framework (which I love)

Peter Senior Director of Heroku Global

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!! Definitely gonna explore it!

@esfoliante_txt

Really love the concept of this framework

@Chrisvidal

Nylo is the best framework for flutter, which makes developing easy

@higakijin

This is incredible. Very well done!

FireflyDaniel

Very nice Framework! Thank you so much!

@ChaoChao2509

I just discovered this framework and I'm very impressed. Thank you

@lepresk

Great work on Nylo

@dylandamsma

This is by far the best framework out there. Amazing quality and features. Thanks so much.

@2kulfi

It's interesting and very amazing. It makes the work more easier and less time consuming. Great work. Thank you

darkreader01

Salut. Je viens juste de d├йcouvrir votre outils et je le trouve vraiment super. Une belle d├йcouverte pour moi ЁЯСМЁЯдМ

ojean-01