diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 12a33e491..20fac2116 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -28,7 +28,7 @@ jobs:
           git config --global user.name uirouter_github_actions
       - name: Install Dependencies
         run: yarn install --pure-lockfile
-      - name: Check Peer Dependencies
-        run: npx check-peer-dependencies
+      #- name: Check Peer Dependencies
+      #  run: npx check-peer-dependencies
       - name: Run yarn ${{ matrix.yarncmd }}
         run: yarn ${{ matrix.yarncmd }}
diff --git a/package.json b/package.json
index f5bc8d6d4..f49742e1a 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
   "peerDependencies": {
     "@angular/common": "^10.0.0 || ^11.0.0",
     "@angular/core": "^10.0.0 || ^11.0.0",
-    "@uirouter/core": "^6.0.7",
+    "@uirouter/core": "^7.0.0-beta.3",
     "@uirouter/rx": "^0.6.0"
   },
   "devDependencies": {
@@ -58,7 +58,7 @@
     "@angular/platform-browser-dynamic": "^10.0.0",
     "@types/jest": "^26.0.4",
     "@types/jquery": "^3.3.33",
-    "@uirouter/core": "^6.0.7",
+    "@uirouter/core": "v7beta",
     "@uirouter/publish-scripts": "2.5.5",
     "@uirouter/rx": "^0.6.0",
     "bufferutil": "4.0.2",
diff --git a/src/directives/uiSref.ts b/src/directives/uiSref.ts
index c332f41a5..71aa7f734 100644
--- a/src/directives/uiSref.ts
+++ b/src/directives/uiSref.ts
@@ -9,8 +9,9 @@ import {
   OnChanges,
   SimpleChanges,
   HostListener,
+  OnInit,
 } from '@angular/core';
-import { UIView, ParentUIViewInject } from './uiView';
+import { UIView } from './uiView';
 import { ReplaySubject, Subscription } from 'rxjs';
 
 /**
@@ -79,7 +80,7 @@ export class AnchorUISref {
   selector: '[uiSref]',
   exportAs: 'uiSref',
 })
-export class UISref implements OnChanges {
+export class UISref implements OnChanges, OnInit {
   /**
    * `@Input('uiSref')` The name of the state to link to
    *
@@ -117,16 +118,16 @@ export class UISref implements OnChanges {
   /** @internal */ private _statesSub: Subscription;
   /** @internal */ private _router: UIRouter;
   /** @internal */ private _anchorUISref: AnchorUISref;
-  /** @internal */ private _parent: ParentUIViewInject;
+  /** @internal */ private _parentUiViewId: string;
 
   constructor(
     _router: UIRouter,
     @Optional() _anchorUISref: AnchorUISref,
-    @Inject(UIView.PARENT_INJECT) parent: ParentUIViewInject
+    @Inject(UIView.PARENT_UIVIEW_ID_TOKEN) parent: string
   ) {
     this._router = _router;
     this._anchorUISref = _anchorUISref;
-    this._parent = parent;
+    this._parentUiViewId = parent;
 
     this._statesSub = _router.globals.states$.subscribe(() => this.update());
   }
@@ -180,8 +181,9 @@ export class UISref implements OnChanges {
   }
 
   getOptions() {
+    const parent = this._router.viewService._pluginapi._registeredUIView(this._parentUiViewId);
     const defaultOpts: TransitionOptions = {
-      relative: this._parent && this._parent.context && this._parent.context.name,
+      relative: parent?.contentState?.name,
       inherit: true,
       source: 'sref',
     };
diff --git a/src/directives/uiView.ts b/src/directives/uiView.ts
index cac7a8e04..a599696e4 100755
--- a/src/directives/uiView.ts
+++ b/src/directives/uiView.ts
@@ -8,19 +8,16 @@ import {
   Input,
   OnDestroy,
   OnInit,
-  ReflectiveInjector,
   ViewChild,
   ViewContainerRef,
 } from '@angular/core';
 
 import {
-  ActiveUIView,
   filter,
   inArray,
   isFunction,
   NATIVE_INJECTOR_TOKEN,
   Param,
-  parse,
   PathNode,
   ResolveContext,
   StateDeclaration,
@@ -29,21 +26,11 @@ import {
   TransitionHookFn,
   UIRouter,
   unnestR,
-  ViewConfig,
-  ViewContext,
 } from '@uirouter/core';
+import { UIViewPortalRenderCommand } from '@uirouter/core/lib/view/interface';
 import { Ng2ViewConfig } from '../statebuilders/views';
 import { MergeInjector } from '../mergeInjector';
 
-/** @hidden */
-let id = 0;
-
-/** @internal These are provide()d as the string UIView.PARENT_INJECT */
-export interface ParentUIViewInject {
-  context: ViewContext;
-  fqn: string;
-}
-
 /** @internal */
 interface InputMapping {
   token: string;
@@ -113,14 +100,24 @@ const ng2ComponentInputs = (factory: ComponentFactory<any>): InputMapping[] => {
   exportAs: 'uiView',
   template: `
     <ng-template #componentTarget></ng-template>
-    <ng-content *ngIf="!_componentRef"></ng-content>
+    <ng-content *ngIf="!_componentRef && !_renderInterop"></ng-content>
+    <div #interopDiv *ngIf="_renderInterop"></div>
   `,
 })
 export class UIView implements OnInit, OnDestroy {
-  static PARENT_INJECT = 'UIView.PARENT_INJECT';
+  /** This injection token is used to inject the parent UIView ID */
+  static PARENT_UIVIEW_ID_TOKEN = 'UIView.PARENT_INJECT';
 
   @ViewChild('componentTarget', { read: ViewContainerRef, static: true })
   _componentTarget: ViewContainerRef;
+
+  @ViewChild('interopDiv', { read: ViewContainerRef })
+  set interopDiv(ref: ViewContainerRef) {
+    if (this._renderCommand.portalContentType === 'RENDER_INTEROP_DIV') {
+      this._renderCommand.giveDiv(ref.element.nativeElement);
+    }
+  }
+
   @Input('name') name: string;
 
   @Input('ui-view')
@@ -136,40 +133,41 @@ export class UIView implements OnInit, OnDestroy {
   private _deregisterUiCanExitHook: Function;
   /** Deregisters the master uiOnParamsChanged transition hook */
   private _deregisterUiOnParamsChangedHook: Function;
+
   /** Data about the this UIView */
-  private _uiViewData: ActiveUIView = <any>{};
-  private _parent: ParentUIViewInject;
+  private _id: string;
+  private _parentUIViewId: string;
+  protected _renderCommand: UIViewPortalRenderCommand;
+  /** @internal */
+  _renderInterop = false;
 
   constructor(
     public router: UIRouter,
-    @Inject(UIView.PARENT_INJECT) parent,
+    @Inject(UIView.PARENT_UIVIEW_ID_TOKEN) parentUIViewId: string,
     public viewContainerRef: ViewContainerRef
   ) {
-    this._parent = parent;
+    this._parentUIViewId = parentUIViewId;
+  }
+
+  private _getViewConfig(): Ng2ViewConfig {
+    if (this._renderCommand?.portalContentType === 'RENDER_ROUTED_VIEW') {
+      return this._renderCommand.uiViewPortalRegistration.viewConfig as Ng2ViewConfig;
+    }
   }
 
   /**
    * @returns the UI-Router `state` that is filling this uiView, or `undefined`.
    */
   public get state(): StateDeclaration {
-    return parse('_uiViewData.config.viewDecl.$context.self')(this);
+    return this._renderCommand.portalContentType === 'RENDER_ROUTED_VIEW'
+      ? this._renderCommand.uiViewPortalRegistration.contentState
+      : undefined;
   }
 
   ngOnInit() {
     const router = this.router;
-    const parentFqn = this._parent.fqn;
     const name = this.name || '$default';
 
-    this._uiViewData = {
-      $type: 'ng2',
-      id: id++,
-      name: name,
-      fqn: parentFqn ? parentFqn + '.' + name : name,
-      creationContext: this._parent.context,
-      configUpdated: this._viewConfigUpdated.bind(this),
-      config: undefined,
-    };
-
     this._deregisterUiCanExitHook = router.transitionService.onBefore({}, (trans) => {
       return this._invokeUiCanExitHook(trans);
     });
@@ -178,7 +176,8 @@ export class UIView implements OnInit, OnDestroy {
       this._invokeUiOnParamsChangedHook(trans)
     );
 
-    this._deregisterUIView = router.viewService.registerUIView(this._uiViewData);
+    const renderContentIntoUIViewPortal = this._renderContentIntoUIViewPortal.bind(this);
+    router.viewService._pluginapi._registerView('ng2', this._parentUIViewId, name, renderContentIntoUIViewPortal);
   }
 
   /**
@@ -212,14 +211,14 @@ export class UIView implements OnInit, OnDestroy {
     const uiOnParamsChanged: TransitionHookFn = instance && instance.uiOnParamsChanged;
 
     if (isFunction(uiOnParamsChanged)) {
-      const viewState: StateDeclaration = this.state;
-      const resolveContext: ResolveContext = new ResolveContext(this._uiViewData.config.path);
+      const resolveContext: ResolveContext = new ResolveContext(this._getViewConfig()?.path ?? []);
       const viewCreationTrans = resolveContext.getResolvable('$transition$').data;
 
       // Exit early if the $transition$ is the same as the view was created within.
       // Exit early if the $transition$ will exit the state the view is for.
-      if ($transition$ === viewCreationTrans || $transition$.exiting().indexOf(viewState as StateDeclaration) !== -1)
+      if ($transition$ === viewCreationTrans || $transition$.exiting().indexOf(this.state) !== -1) {
         return;
+      }
 
       const toParams: { [paramName: string]: any } = $transition$.params('to');
       const fromParams: { [paramName: string]: any } = $transition$.params('from');
@@ -249,40 +248,46 @@ export class UIView implements OnInit, OnDestroy {
   }
 
   ngOnDestroy() {
-    if (this._deregisterUIView) this._deregisterUIView();
+    if (this._id) this.router.viewService._pluginapi._deregisterView(this._id);
     if (this._deregisterUiCanExitHook) this._deregisterUiCanExitHook();
     if (this._deregisterUiOnParamsChangedHook) this._deregisterUiOnParamsChangedHook();
     this._deregisterUIView = this._deregisterUiCanExitHook = this._deregisterUiOnParamsChangedHook = null;
     this._disposeLast();
   }
 
+  private _saveUiViewId(uiViewId: string) {
+    if (typeof this._id === 'string' && this._id !== uiViewId) {
+      throw new Error(
+        `Received a render command for wrong UIView. Render command id: ${uiViewId}, UIView id: ${this._id}`
+      );
+    }
+
+    this._id = uiViewId;
+  }
+
   /**
-   * The view service is informing us of an updated ViewConfig
+   * The view service is informing us to change what we are rendering in the portal
    * (usually because a transition activated some state and its views)
    */
-  _viewConfigUpdated(config: ViewConfig) {
-    // The config may be undefined if there is nothing currently targeting this UIView.
-    // Dispose the current component, if there is one
-    if (!config) return this._disposeLast();
-
-    // Only care about Ng2 configs
-    if (!(config instanceof Ng2ViewConfig)) return;
-
-    // The "new" viewconfig is already applied, so exit early
-    if (this._uiViewData.config === config) return;
-
-    // This is a new ViewConfig.  Dispose the previous component
+  _renderContentIntoUIViewPortal(renderCommand: UIViewPortalRenderCommand): void {
+    this._renderCommand = renderCommand;
+    this._saveUiViewId(renderCommand.uiViewPortalRegistration.id); // Dispose the previous component
     this._disposeLast();
-    trace.traceUIViewConfigUpdated(this._uiViewData, config && config.viewDecl.$context);
 
-    this._applyUpdatedConfig(config);
+    // UIView template will handle RENDER_INTEROP_DIV and RENDER_DEFAULT_CONTENT
+    this._renderInterop = renderCommand.portalContentType === 'RENDER_INTEROP_DIV';
+
+    if (renderCommand.portalContentType === 'RENDER_ROUTED_VIEW') {
+      const registeredportal = this.router.viewService._pluginapi._registeredUIView(this._id);
+      trace.traceUIViewConfigUpdated(registeredportal as any, this.state.$$state()); // TODO: move to core
+      this._renderRoutedConfigComponent(renderCommand.uiViewPortalRegistration.viewConfig);
+    }
 
     // Initiate change detection for the newly created component
-    this._componentRef.changeDetectorRef.markForCheck();
+    this._componentRef?.changeDetectorRef.markForCheck();
   }
 
-  private _applyUpdatedConfig(config: Ng2ViewConfig) {
-    this._uiViewData.config = config;
+  private _renderRoutedConfigComponent(config: Ng2ViewConfig) {
     // Create the Injector for the routed component
     const context = new ResolveContext(config.path);
     const componentInjector = this._getComponentInjector(context);
@@ -317,15 +322,13 @@ export class UIView implements OnInit, OnDestroy {
       .filter((r) => r.resolved);
 
     const newProviders = resolvables.map((r) => ({ provide: r.token, useValue: context.injector().get(r.token) }));
-
-    const parentInject = { context: this._uiViewData.config.viewDecl.$context, fqn: this._uiViewData.fqn };
-    newProviders.push({ provide: UIView.PARENT_INJECT, useValue: parentInject });
+    newProviders.push({ provide: UIView.PARENT_UIVIEW_ID_TOKEN, useValue: this._id });
 
     const parentComponentInjector = this.viewContainerRef.injector;
     const moduleInjector = context.getResolvable(NATIVE_INJECTOR_TOKEN).data;
     const mergedParentInjector = new MergeInjector(moduleInjector, parentComponentInjector);
 
-    return ReflectiveInjector.resolveAndCreate(newProviders, mergedParentInjector);
+    return Injector.create({ providers: newProviders, parent: mergedParentInjector });
   }
 
   /**
@@ -335,7 +338,7 @@ export class UIView implements OnInit, OnDestroy {
    * to the resolve data.
    */
   private _applyInputBindings(factory: ComponentFactory<any>, component: any, context: ResolveContext, componentClass) {
-    const bindings = this._uiViewData.config.viewDecl['bindings'] || {};
+    const bindings = this._getViewConfig()?.viewDecl?.bindings ?? {};
     const explicitBoundProps = Object.keys(bindings);
 
     // Returns the actual component property for a renamed an input renamed using `@Input('foo') _foo`.
diff --git a/src/providers.ts b/src/providers.ts
index d47602037..e7fbb3e62 100644
--- a/src/providers.ts
+++ b/src/providers.ts
@@ -99,7 +99,7 @@ import {
   Resolvable,
   NATIVE_INJECTOR_TOKEN,
 } from '@uirouter/core';
-import { UIView, ParentUIViewInject } from './directives/uiView';
+import { UIView } from './directives/uiView';
 import { UIROUTER_MODULE_TOKEN, UIROUTER_ROOT_MODULE } from './injectionTokens';
 import { ng2ViewsBuilder, Ng2ViewConfig } from './statebuilders/views';
 import { Ng2ViewDeclaration } from './interface';
@@ -183,17 +183,13 @@ export function appInitializer(router: UIRouter) {
   };
 }
 
-export function parentUIViewInjectFactory(r: StateRegistry) {
-  return { fqn: null, context: r.root() } as ParentUIViewInject;
-}
-
 export const _UIROUTER_INSTANCE_PROVIDERS: Provider[] = [
   {
     provide: UIRouter,
     useFactory: uiRouterFactory,
     deps: [LocationStrategy, UIROUTER_ROOT_MODULE, UIROUTER_MODULE_TOKEN, Injector],
   },
-  { provide: UIView.PARENT_INJECT, useFactory: parentUIViewInjectFactory, deps: [StateRegistry] },
+  { provide: UIView.PARENT_UIVIEW_ID_TOKEN, useValue: null, deps: [StateRegistry] },
   { provide: APP_INITIALIZER, useFactory: appInitializer, deps: [UIRouter], multi: true },
 ];
 
diff --git a/yarn.lock b/yarn.lock
index b0167575d..deaf50436 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -763,10 +763,10 @@
   dependencies:
     "@types/yargs-parser" "*"
 
-"@uirouter/core@^6.0.7":
-  version "6.0.7"
-  resolved "https://registry.yarnpkg.com/@uirouter/core/-/core-6.0.7.tgz#a66743dceb13a56d8908474ff891d63e5d5a2b01"
-  integrity sha512-KUTJxL+6q0PiBnFx4/Z+Hsyg0pSGiaW5yZQeJmUxknecjpTbnXkLU8H2EqRn9N2B+qDRa7Jg8RcgeNDPY72O1w==
+"@uirouter/core@v7beta":
+  version "7.0.0-beta.3"
+  resolved "https://registry.yarnpkg.com/@uirouter/core/-/core-7.0.0-beta.3.tgz#a4df98267d5aa4f512b545cc1535f20192270f8e"
+  integrity sha512-T4UT0V2MgadE+Z/ZaB8bc/QhZdvw0foQWWb/BrVCxoKDZJMghxAk7/7PI3KGRTBvJkk+Py0n2INafwGlPH4M+w==
 
 "@uirouter/publish-scripts@2.5.5":
   version "2.5.5"
