Guidelines for structuring and developing IntelliJ remote development modules. Use when working on Remote Development features.
.frontend - UI code that runs on client side.backend - computation code that runs on server side.shared - code common to both frontend and backend@Rpc annotation in shared moduleRemoteApiProvider to register implementationssuspend functions@SerializableVirtualFile.rpcId() and VirtualFileId.virtualFile())StateFlow and FlowDetailed documentation in docs/IntelliJ-Platform/4_man/Remote-Development/:
External: Remote Development Overview (user documentation)
Standard Module: intellij.<pluginGroup>.<frameworkName>
Example: intellij.java.dsm, intellij.cidr.debugger
Remote Development Modules (split architecture):
intellij.<feature>intellij.<feature>.rpc (for RPC interfaces)intellij.<feature>.backendintellij.<feature>.frontendintellij.<feature>.frontend.split, intellij.<feature>.backend.splitplatform/feature/ following V2 plugin formatplatform/feature-rpc/ for RPC interfaces@Rpc interfaces, DTOs, and supporting classesplatform/feature/backend/intellij.platform.feature.backend.xml in resourcesintellij.platform.backendessential-modules.xmlplatform/feature/frontend/intellij.platform.feature.frontend.xml in resourcesintellij.platform.frontendessential-modules.xml and intellij.platform.frontend.main.imlremote-dev/feature/frontend.split.rpc suffix for RPC interfaces.backend suffix as V2 plugin moduleintellij.platform.backend and .rpc module.frontend suffix as V2 plugin moduleintellij.platform.frontend and .rpc module.frontend.split suffix in appropriate locationintellij.platform.frontend.splitThe following patterns are essential when implementing reactive UI components for Remote Development:
.toRpc() extension to convert StateFlow to RpcFlow for RPC transfertoFlow().stateIn() pattern to convert RpcFlow to StateFlowExample: Reactive Breakpoint DTO
// Flow-based DTO with initial values
@Serializable
data class XBreakpointDto(
// Static properties
val displayText: String,
val iconId: IconId,
val sourcePosition: XSourcePositionDto?,
// Initial values for immediate use
val initialEnabled: Boolean,
val initialSuspendPolicy: SuspendPolicy,
// Reactive flow fields
val enabledState: RpcFlow<Boolean>,
val suspendPolicyState: RpcFlow<SuspendPolicy>,
)
Example: Frontend Component with Reactive State
class FrontendXBreakpointProxy(
private val project: Project,
private val cs: CoroutineScope,
private val dto: XBreakpointDto
) {
// Convert RpcFlow to StateFlow with initial values
val enabled: StateFlow<Boolean> = dto.enabledState.toFlow()
.stateIn(cs, SharingStarted.Eagerly, dto.initialEnabled)
// Access current value from StateFlow
fun isEnabled(): Boolean = enabled.value
}