V7 Nylo v7 출시! 새로운 기능 보기 →
Nylo
Flutter 마이크로 프레임워크 MIT 라이선스

Flutter
마이크로 프레임워크
현대적인 앱을 위한

Nylo는 모든 프로젝트에 동일하고 탄탄한 기반(라우팅, 상태, 네트워킹, 폼, 인증)을 제공합니다. 덕분에 첫 번째 파일이 아니라 첫 번째 기능부터 시작할 수 있습니다.

한 줄로 설치
$ dart pub global activate nylo_installer
설치 가이드 읽기 그런 다음 안내에 따라 프로젝트 이름을 정하세요.
my_app 생성됨
lib/
app/  — 모델, 네트워킹, 프로바이더
bootstrap/  — 부팅 및 설정
config/  — 테마, 키, 디코더
resources/
pages/  home_page.dart
widgets/
themes/
routes/  router.dart
main.dart
모든 Nylo 프로젝트는 같은 구조로 시작합니다. 동료의 프로젝트도 마찬가지입니다.
864 ★ GitHub 스타 Dart 3 호환 MIT 라이선스 pub.dev에 nylo.dev가 배포 2021년부터 꾸준히 관리되고 있습니다
>_ Metro CLI

터미널에서 무엇이든 생성

Metro는 페이지, 모델, 컨트롤러, 위젯 등을 생성합니다. 한쪽 구석에 던져두는 것이 아니라 라우터와 폴더 구조에 제대로 연결된 상태로요.

위젯, 앱 기반 구조, 설정까지 아우르는 17개의 제너레이터
생성할 때 라우트가 자동으로 등록됩니다
팀 전체에서 일관된 이름과 파일 위치
Metro에 대해 더 알아보기
zsh — my_app
$ metro make:page HomePage
  ✓ Created lib/resources/pages/home_page.dart
$ metro make:api_service User
  ✓ Created lib/app/networking/user_api_service.dart
$ metro make:model User
  ✓ Created lib/app/models/user.dart
$ metro make:stateful_widget FavouriteWidget
app/networking/api_service.dart
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 서비스를 작성하세요. 페이지에 Dio 상용구 코드는 필요 없습니다.

네트워킹에 대해 더 알아보기
살펴보기

실제로 작성할 코드에서 확인해 보세요

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 폼으로 한 곳에서 데이터를 관리, 검증, 제출하세요.

더 알아보기
단계 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()

상태 유지와 함께 하단 내비게이션, 상단 내비게이션 또는 여정 흐름을 구축하세요.

더 알아보기
커뮤니티

공개적으로 개발되고, 실제 서비스에서 사용됩니다

“Dart도 이 프레임워크도 처음인데, 정말 마음에 듭니다.”

P
Peter
시니어 디렉터, Heroku Global

“Nylo는 Flutter를 위한 최고의 프레임워크입니다. 개발이 쉬워집니다.”

@higakijin

“단연코 최고의 프레임워크입니다. 품질과 기능 모두 훌륭합니다.”

@2kulfi

“작업이 더 쉬워지고 시간도 줄어듭니다. 훌륭합니다.”

darkreader01

“이 프레임워크를 막 알게 되었는데 정말 인상적입니다. 감사합니다.”

@lepresk

“이 프레임워크의 개념이 정말 마음에 듭니다.”

@Chrisvidal

“여러분이 하고 계신 훌륭한 작업에 감사드리고 싶었습니다.”

@youssefKadaouiAbbassi

“@nylo_dev 웹사이트가 정말 마음에 든다고 말하고 싶었어요!”

@esfoliante_txt

“정말 대단합니다. 아주 잘 만들었어요!”

FireflyDaniel

당신의 다음 Flutter 앱은 명령어 하나로 시작됩니다

무료, MIT 라이선스, 그리고 그 안은 여전히 순수한 Flutter입니다.

$ dart pub global activate nylo_installer