Genkit Dart: Come Costruire App AI Full-Stack con Flutter e Dart [Guida 2026]

Introduzione: cos’è Genkit Dart e perché dovresti conoscerlo

Se sviluppi app con Flutter, probabilmente hai già iniziato a chiederti come integrare l’AI nei tuoi progetti. La risposta di Google si chiama Genkit Dart — e cambia le regole del gioco.

Annunciato a inizio 2026, Genkit Dart è il porting in Dart del framework AI open-source di Google. La promessa è semplice ma potente: costruire app AI complete — frontend Flutter e backend Dart — nello stesso linguaggio, con gli stessi strumenti, senza cambiare contesto.

Il punto di forza principale? È model-agnostic. Puoi usare Google Gemini, Anthropic Claude o OpenAI GPT e passare da uno all’altro con una sola riga di codice. Noi di SpaghettiCoders lo stiamo già sperimentando su progetti reali, e in questa guida ti mostriamo tutto quello che hai bisogno per iniziare.

Setup: installazione e primo progetto in 5 minuti

Per iniziare, aggiunge le dipendenze nel tuo pubspec.yaml:

yaml

dependencies:
  genkit: ^0.1.0
  genkit_google_ai: ^0.1.0   # oppure genkit_anthropic, genkit_openai

dev_dependencies:
  genkit_cli: ^0.1.0

Poi inizializza Genkit nel tuo backend Dart:

dart

import 'package:genkit/genkit.dart';
import 'package:genkit_google_ai/genkit_google_ai.dart';

void main() async {
  final ai = Genkit(
    plugins: [googleAI()],
  );

  // Il tuo server è pronto
  await ai.startFlowServer();
}

Installa la CLI globalmente con dart pub global activate genkit_cli e lancia il progetto con genkit start. In pochi secondi hai la Developer UI accessibile su localhost:4000 — un pannello interattivo per testare i tuoi flow AI senza scrivere un singolo test.

Primo flow AI: generatore di ricette tipizzato

Un “flow” in Genkit è una funzione AI definita con schema di input e output. Ecco un esempio concreto — un generatore di ricette che restituisce dati strutturati:

dart

import 'package:genkit/genkit.dart';

// Schema tipizzato per l'output
class Recipe {
  final String name;
  final List<String> ingredients;
  final String instructions;
  final int prepTimeMinutes;

  Recipe({
    required this.name,
    required this.ingredients,
    required this.instructions,
    required this.prepTimeMinutes,
  });
}

// Definizione del flow
final recipeFlow = defineFlow(
  name: 'generateRecipe',
  inputSchema: Schema.string(),
  outputSchema: Schema.object<Recipe>(),
  fn: (ingredient) async {
    final response = await generate(
      model: gemini15Flash,
      prompt: 'Crea una ricetta italiana usando: $ingredient. '
              'Rispondi in formato JSON con name, ingredients, instructions e prepTimeMinutes.',
      output: OutputConfig(schema: Schema.object<Recipe>()),
    );
    return response.output!;
  },
);

Il risultato è un oggetto Recipe completamente tipizzato — niente Map<String, dynamic>, niente parsing manuale. Genkit gestisce la traduzione da testo AI a oggetti Dart per te.

Type Safety con Schemantic: output strutturato end-to-end

Uno dei problemi classici quando si integra un LLM in un’app è la fragilità dell’output: il modello restituisce JSON “quasi corretto” e il tuo parser va in crash. Genkit risolve questo con Schemantic, il suo sistema di schema tipizzato.

Definisci lo schema una volta e Genkit:

  • istruisce il modello a rispettare la struttura
  • valida l’output ricevuto
  • rilancia la generazione se la validazione fallisce

dart

final schema = Schema.object({
  'titolo': Schema.string(description: 'Titolo della ricetta'),
  'ingredienti': Schema.array(Schema.string()),
  'difficolta': Schema.enumValue(['facile', 'media', 'difficile']),
});

Questo si traduce in type safety end-to-end: da Flutter fino al modello AI e di ritorno, senza eccezioni runtime sorprendenti.

Multi-model: switcha tra Gemini, Claude e GPT in una riga

Uno dei vantaggi più pratici di Genkit è la portabilità tra modelli. Bastano due cambiamenti:

dart

// Con Google Gemini
import 'package:genkit_google_ai/genkit_google_ai.dart';
final ai = Genkit(plugins: [googleAI()]);
// model: gemini15Flash

// Con Anthropic Claude
import 'package:genkit_anthropic/genkit_anthropic.dart';
final ai = Genkit(plugins: [anthropic()]);
// model: claude35Sonnet

// Con OpenAI
import 'package:genkit_openai/genkit_openai.dart';
final ai = Genkit(plugins: [openAI()]);
// model: gpt4o

Il resto del codice — i flow, gli schema, la logica — rimane identico. Perfetto per confrontare modelli, abbattere i costi o usare modelli diversi per task diversi nella stessa app.

Tool Calling: agenti AI con strumenti tipizzati

Il tool calling è la funzionalità che trasforma un LLM da “generatore di testo” a “agente capace di agire”. Con Genkit definisci strumenti tipizzati che il modello può invocare autonomamente:

dart

final weatherTool = defineTool(
  name: 'getWeather',
  description: 'Ottieni le condizioni meteo per una città',
  inputSchema: Schema.object({
    'city': Schema.string(),
    'country': Schema.string(),
  }),
  outputSchema: Schema.object({
    'temperature': Schema.number(),
    'condition': Schema.string(),
  }),
  fn: (input) async {
    // Chiama la tua API meteo reale
    return await weatherApi.fetch(input['city'], input['country']);
  },
);

// Il modello decide autonomamente quando e come usare il tool
final response = await generate(
  model: gemini15Flash,
  prompt: 'Che tempo fa a Napoli oggi? Suggerisci un outfit.',
  tools: [weatherTool],
);

Il modello capisce quando invocare lo strumento, passa i parametri corretti, riceve il risultato e lo integra nella risposta finale — tutto in automatico.

Architettura Flutter: 3 pattern per integrare Genkit

Esistono tre approcci principali per connettere Flutter a Genkit, ognuno con pro e contro:

1. Client-side (solo per prototipi) Il flow gira direttamente sul device. Semplice da implementare, ma espone le API key e non scala.

2. Server-side (produzione) Flutter chiama un server Dart che espone i flow via HTTP. Il pattern consigliato per app reali.

dart

// Nel tuo provider Riverpod (come vediamo nel nostro corso Flutter - Lezione 7)
final recipeProvider = FutureProvider.family<Recipe, String>((ref, ingredient) async {
  final response = await http.post(
    Uri.parse('https://api.tuaapp.com/generateRecipe'),
    body: json.encode({'ingredient': ingredient}),
  );
  return Recipe.fromJson(json.decode(response.body));
});

3. Ibrido Flow leggeri on-device, flow pesanti o con dati sensibili sul server. Utile per app con funzionalità offline parziali.

Deploy: Shelf server, Docker e Firebase Functions

Genkit Dart supporta più strategie di deploy. La più interessante per il mondo Flutter è Firebase Cloud Functions con Dart:

dockerfile

# Dockerfile per il tuo server Genkit
FROM dart:stable AS build
WORKDIR /app
COPY pubspec.* ./
RUN dart pub get
COPY . .
RUN dart compile exe bin/server.dart -o bin/server

FROM debian:bullseye-slim
COPY --from=build /app/bin/server /app/bin/server
EXPOSE 8080
CMD ["/app/bin/server"]

Con Shelf come HTTP server e Firebase come infrastruttura, si ottengono cold start nell’ordine dei 10ms — performance difficili da raggiungere con Node.js o Python nelle stesse condizioni.

Per un server Shelf minimale:

dart

import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart';
import 'package:genkit/genkit.dart';

void main() async {
  final ai = Genkit(plugins: [googleAI()]);
  
  final handler = const Pipeline()
    .addMiddleware(logRequests())
    .addHandler(ai.httpHandler());

  await serve(handler, '0.0.0.0', 8080);
  print('Server in ascolto su porta 8080');
}

Developer UI: testa i flow senza scrivere test

Una delle killer feature di Genkit è la Developer UI integrata. Lanciando genkit start, ottieni un pannello web su localhost:4000 dove puoi:

  • eseguire qualsiasi flow con input personalizzati
  • vedere input, output e trace completo di ogni run
  • ispezionare le chiamate al modello e i tool invocati
  • confrontare output di run diverse

È il modo più rapido per iterare sul comportamento dei tuoi flow AI durante lo sviluppo — senza bisogno di costruire un’interfaccia di test separata.

Quando usare Genkit Dart vs alternative

Genkit Dart è la scelta giusta quando:

✅ Il tuo team conosce già Dart/Flutter e vuole evitare di imparare Node.js o Python per il backend AI ✅ Hai bisogno di type safety end-to-end tra frontend e backend ✅ Vuoi la flessibilità di cambiare modello AI senza riscrivere la logica ✅ Stai costruendo su Firebase e vuoi deploy rapidi con cold start bassi

Considera le alternative se:

  • Il tuo backend è già in Python (LangChain, LlamaIndex sono più maturi per quell’ecosistema)
  • Hai bisogno di feature avanzate di RAG o vector store (l’ecosistema Genkit Dart è ancora giovane)
  • Il tuo team ha più esperienza con l’ecosistema JavaScript (Genkit JS è più avanzato)

Conclusioni e prossimi passi

Genkit Dart è ancora giovane — la versione 0.1.x porta con sé alcune limitazioni rispetto al porting JavaScript — ma la direzione è chiara e promettente. Per i team Flutter che vogliono abbracciare l’AI senza abbandonare l’ecosistema Dart, è già oggi lo strumento più coerente disponibile.

Noi di SpaghettiCoders lo stiamo usando su progetti reali e continueremo a documentare l’esperienza in questa serie. Nel prossimo articolo esploreremo come costruire un RAG (Retrieval-Augmented Generation) completo con Genkit Dart e un vector store — stay tuned.

Risorse utili:


🎓 Vuoi imparare Flutter da zero? Nel nostro Corso Flutter trovi tutto quello che ti serve per diventare uno sviluppatore Flutter completo — dalla Lezione 1 sulle basi fino alla Lezione 7 su Riverpod e MVVM, lo stesso stack che usiamo in questa guida.

Preferisci iniziare gratis? Dai un’occhiata al nostro corso YouTube gratuito oppure aspetta il prossimo corso live in partenza.

Condividi il post:

Leggi anche