> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. # What is gRPC? > gRPC is a high-performance RPC framework that uses Protocol Buffers #### Enterprise feature for SDKs Using this feature in generated SDKs requires the [Enterprise plan](https://buildwithfern.com/pricing). To get started, reach out to [support@buildwithfern.com](mailto:support@buildwithfern.com). Fern only supports gRPC SDK generation for .NET/C#. Protobuf specs can be used for documentation generation in all languages. [File an issue](https://github.com/fern-api/fern/issues) to request additional languages. gRPC is a modern, open-source, high-performance Remote Procedure Call (RPC) framework that can run in any environment. It uses Protocol Buffers (protobuf) as the interface definition language and supports multiple programming languages. Fern is compatible with gRPC services and can generate SDKs and documentation from your `.proto` files. For a working example, see the [gRPC demo docs](https://grpc-demo.docs.buildwithfern.com/) and its [GitHub repository](https://github.com/fern-demo/grpc-demo). Below is an example of a gRPC service definition: **`user_service.proto`** ```protobuf user_service.proto syntax = "proto3"; package userservice.v1; // User service for managing user accounts service UserService { // Create a new user account rpc CreateUser(CreateUserRequest) returns (User); // Get user by ID rpc GetUser(GetUserRequest) returns (User); // List users with pagination rpc ListUsers(ListUsersRequest) returns (ListUsersResponse); // Update user information rpc UpdateUser(UpdateUserRequest) returns (User); // Delete a user account rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty); // Stream user events (server streaming) rpc StreamUserEvents(StreamUserEventsRequest) returns (stream UserEvent); // Upload user data (client streaming) rpc UploadUserData(stream UploadUserDataRequest) returns (UploadUserDataResponse); // Real-time chat (bidirectional streaming) rpc Chat(stream ChatMessage) returns (stream ChatMessage); } // Messages for user operations message User { string id = 1; string email = 2; string name = 3; int32 age = 4; google.protobuf.Timestamp created_at = 5; UserStatus status = 6; } message CreateUserRequest { string email = 1; string name = 2; int32 age = 3; } message GetUserRequest { string id = 1; } message ListUsersRequest { int32 page_size = 1; string page_token = 2; string filter = 3; } message ListUsersResponse { repeated User users = 1; string next_page_token = 2; int32 total_count = 3; } message UpdateUserRequest { string id = 1; User user = 2; google.protobuf.FieldMask update_mask = 3; } message DeleteUserRequest { string id = 1; } message StreamUserEventsRequest { string user_id = 1; repeated UserEventType event_types = 2; } message UserEvent { string id = 1; string user_id = 2; UserEventType type = 3; google.protobuf.Timestamp timestamp = 4; google.protobuf.Any data = 5; } message UploadUserDataRequest { oneof data { UserDataChunk chunk = 1; UserDataMetadata metadata = 2; } } message UserDataChunk { bytes data = 1; int64 offset = 2; } message UserDataMetadata { string filename = 1; int64 total_size = 2; string content_type = 3; } message UploadUserDataResponse { string file_id = 1; int64 bytes_uploaded = 2; } message ChatMessage { string id = 1; string user_id = 2; string room_id = 3; string content = 4; google.protobuf.Timestamp timestamp = 5; ChatMessageType type = 6; } // Enums enum UserStatus { USER_STATUS_UNSPECIFIED = 0; USER_STATUS_ACTIVE = 1; USER_STATUS_INACTIVE = 2; USER_STATUS_SUSPENDED = 3; } enum UserEventType { USER_EVENT_TYPE_UNSPECIFIED = 0; USER_EVENT_TYPE_CREATED = 1; USER_EVENT_TYPE_UPDATED = 2; USER_EVENT_TYPE_DELETED = 3; USER_EVENT_TYPE_LOGIN = 4; USER_EVENT_TYPE_LOGOUT = 5; } enum ChatMessageType { CHAT_MESSAGE_TYPE_UNSPECIFIED = 0; CHAT_MESSAGE_TYPE_TEXT = 1; CHAT_MESSAGE_TYPE_IMAGE = 2; CHAT_MESSAGE_TYPE_FILE = 3; CHAT_MESSAGE_TYPE_SYSTEM = 4; } ``` ## Set up your fern folder #### Create your fern directory Create a `fern/` folder in your project root. ``` fern/ ``` #### Add your gRPC service Add your gRPC files to the fern directory. You can place it in a subfolder called `proto` or directly in the fern directory. ``` fern/ └─ proto/ ├─ user_service.proto └─ common.proto ``` #### Create a \`fern.config.json\` file Add a `fern.config.json` file in your fern directory that lists your organization and the current version of the Fern CLI: **`fern.config.json`** ```json title="fern.config.json" { "organization": "your-organization", "version": "5.23.3" } ``` ``` fern/ ├─ fern.config.json └─ proto/ ├─ user_service.proto └─ common.proto ``` #### Create a \`generators.yml\` file Create a `generators.yml` file in your fern directory and add a reference to your gRPC proto files. See [gRPC generators.yml reference](/learn/api-definitions/grpc/generators-yml-reference) for complete configuration options. **`generators.yml`** ```yaml title="generators.yml" # Your API definition api: specs: - proto: # Path up to where package starts (e.g., for package userservice.v1) root: ../user-service/proto # Omit to generate docs for entire root folder target: ../user-service/proto/data/v1/user_service.proto groups: external: generators: # Your C# generator configuration here, if relevant ``` If you want to [compile `.proto` files locally (`local-generation: true`)](/learn/api-definitions/grpc/generators-yml-reference#local-generation), you must have [buf](https://buf.build/docs/installation) installed on your machine or [in your CI/CD environment](/learn/api-definitions/grpc/sync-your-g-rpc-specification). Your final directory structure: ``` fern/ ├─ fern.config.json ├─ generators.yml └─ proto/ ├─ user_service.proto └─ common.proto ``` > gRPC is a high-performance RPC framework that uses Protocol Buffers